octave-maintainers
[Top][All Lists]
Advanced

[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 &param_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);
    }

}

reply via email to

[Prev in Thread] Current Thread [Next in Thread]