[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
parameter checking
From: |
Stefan van der Walt |
Subject: |
parameter checking |
Date: |
Mon, 09 Feb 2004 11:10:34 +0200 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.5) Gecko/20031107 Debian/1.5-3 |
Hi all
I have attached code to do simple parameter checking and updating (when
writing oct-modules in C++).
It can be used as follows:
if (param_check("rm [rs rs rs]", args, "b = blah(u[, f, t, p]") {
...
}
This ensures that the first parameter is a real matrix and that, if any
of the three optional parameters are specified, they are real scalars.
The string describing the parameters is documented in the code attached.
param_update(default_args, args);
This updates the default arguments with those specified by the user.
An option is to extend the syntax of param_check to allow the following
syntax:
ColumnVector r = param_check("rm|rs|cs rm|cm", ...);
Where r is a vector (e.g. [2 1]) describing which type matched the
parameter ([2 1] => complex-scalar and complex-matrix).
I hope someone finds this even slightly useful...
Regards
Stéfan
/* Copyright (c) 2004, Stefan van der Walt <address@hidden> */
#include <string>
#include <vector>
#include <octave/oct.h>
#include <octave/error.h>
bool param_check(const std::string ¶m_str, const octave_value_list &args,
const std::string usage_str) {
/* code function called
* ---------------------------------------
* c is_cell
* rs is_real_scalar
* rm is_real_matrix
* rnda is_real_nd_array (> 2.1.50)
* cs is_complex_scalar
* cm is_complex_matrix
* bm is_bool_matrix (> 2.1.50)
* chm is_char_matrix
* s is_string
* r is_range
* m is_map
* strm is_stream
* strmoff is_streamoff (>2.1.50)
* cl is_cs_list
* l is_list
*
* + allow extra parameters
*
* example: param_str = "c rs [m +]"
* Requires at least 2 parameters. Parameter 1 must be a cell,
* parameter 2 real and scalar and optional parameter 3 a map.
*
* example: param_str = "rm [rs rs]"
* Requires at least 1 parameter, maximum 3. Parameter 1 must be a
* real, matrix. Parameters 2 and 3 are optional, but if specified
* they must be real and scalar.
*
*
*/
using namespace std;
string::size_type pos = 0, prev_pos = 0;
vector<string> ps; // parameter specifiers
while ( (pos = param_str.find_first_of(' ', pos)) != string::npos ) {
// store parameter specifier
ps.push_back( param_str.substr(prev_pos, pos - prev_pos) );
prev_pos = ++pos;
}
ps.push_back( param_str.substr(prev_pos, pos - prev_pos) );
int mandatory_args = 0;
int optional_args = 0;
bool extra_args = false;
vector<string>::iterator i;
for ( i = ps.begin(); i != ps.end(); i++ ) {
string param = (string)*i;
if (param[0] == ']') {
ps.erase(i); i--;
} else if (param[0] == '+') {
// extra arguments allowed?
ps.erase(i); i--;
extra_args = true;
} else {
// count nr of mandatory and optional arguments
if (optional_args > 0) {
optional_args++;
} else {
mandatory_args++;
}
if ( param[0] == '[') {
optional_args++;
mandatory_args--;
*i = param.substr(1, param.length() - 1);
}
// remove trailing ']' if necessary
if (param[param.length()-1] == ']') {
*i = param.substr(0, param.length() - 1);
}
}
}
// check: correct nr of parameters
if (args.length() < mandatory_args) {
usage(usage_str.c_str());
return false;
}
if ((args.length() > mandatory_args + optional_args) & (!extra_args)) {
usage(usage_str.c_str());
return false;
}
int nr_checks = args.length();
if (args.length() > ps.size()) {
nr_checks = ps.size();
}
for ( int i = 0; i < nr_checks; i++ ) {
string param = ps[i];
if (ps[i] == "c") {
if (!args(i).is_cell()) {
error("Parameter %i is not a cell!", i+1);
}
}
if (ps[i] == "rs") {
if (!args(i).is_real_scalar()) {
error("Parameter %i is not real and scalar!", i+1);
}
}
if (ps[i] == "rm") {
if (!args(i).is_real_matrix()) {
error("Parameter %i is not a real matrix!", i+1);
}
}
if (ps[i] == "cs") {
if (!args(i).is_complex_scalar()) {
error("Parameter %i is not a complex scalar!", i+1);
}
}
if (ps[i] == "cm") {
if (!args(i).is_complex_matrix()) {
error("Parameter %i is not a complex matrix!", i+1);
}
}
if (ps[i] == "cm") {
if (!args(i).is_complex_matrix()) {
error("Parameter %i is not a complex matrix!", i+1);
}
}
if (ps[i] == "chm") {
if (!args(i).is_char_matrix()) {
error("Parameter %i is not a character matrix!", i+1);
}
}
if (ps[i] == "s") {
if (!args(i).is_string()) {
error("Parameter %i is not a string!", i+1);
}
}
if (ps[i] == "r") {
if (!args(i).is_range()) {
error("Parameter %i is not a range!", i+1);
}
}
if (ps[i] == "m") {
if (!args(i).is_map()) {
error("Parameter %i is not a map!", i+1);
}
}
if (ps[i] == "strm") {
if (!args(i).is_stream()) {
error("Parameter %i is not a stream!", i+1);
}
}
if (ps[i] == "cl") {
if (!args(i).is_cs_list()) {
error("Parameter %i is not a cs_list!", i+1);
}
}
if (ps[i] == "l") {
if (!args(i).is_list()) {
error("Parameter %i is not a list!", i+1);
}
}
/** Only supported by Octave >2.1.50
if (ps[i] == "rnda") {
if (!args(i).is_real_nd_array()) {
error("Parameter %i is not a real N-dim array!", i);
}
}
if (ps[i] == "bm") {
if (!args(i).is_bool_matrix()) {
error("Parameter %i is not a boolean matrix!", i);
}
}
if (ps[i] == "strmoff") {
if (!args(i).is_range()) {
error("Parameter %i is not an offset stream!", i);
}
}
**/
}
return !error_state;
}
void param_update(octave_value_list &default_args, const octave_value_list
&args) {
for (int i = 0; i < std::min(args.length(), default_args.length()); i++) {
default_args(i) = args(i);
}
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- parameter checking,
Stefan van der Walt <=