From octave-maintainers-request at bevo dot che dot wisc dot edu Mon Feb 9 03:59:06 2004 Subject: parameter checking From: Stefan van der Walt To: octave-maintainers at bevo dot che dot wisc dot edu Date: Mon, 09 Feb 2004 11:10:34 +0200 This is a multi-part message in MIME format. --------------060503020704020603040603 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 8bit 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 --------------060503020704020603040603 Content-Type: text/x-chdr; name="oct_param.h" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="oct_param.h" /* Copyright (c) 2004, Stefan van der Walt */ #include #include #include #include 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 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::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); } } --------------060503020704020603040603--