# HG changeset patch # User Jaroslav Hajek # Date 1274100116 -7200 # Node ID e1559a8a60b429d74cfe33eece5b6c171406b1c6 # Parent 9cd5aa83fa62ad38e83057c7bba055c267350cb9 general mechanism for string enum variables diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,11 @@ +2010-05-17 Jaroslav Hajek + + * variables.cc (set_internal_variable (int&, ..., const char **, int)): + New overload. + * variables.h: Declare it. + (SET_INTERNAL_VARIABLE_CHOICES): New macro. + * DLD-FUNCTIONS/svd.cc (Fsvd_driver): Use it here. + 2010-05-17 Jaroslav Hajek * ov-usr-fcn.h (octave_user_function::curr_unwind_protect_frame): New diff --git a/src/DLD-FUNCTIONS/svd.cc b/src/DLD-FUNCTIONS/svd.cc --- a/src/DLD-FUNCTIONS/svd.cc +++ b/src/DLD-FUNCTIONS/svd.cc @@ -36,8 +36,9 @@ #include "oct-obj.h" #include "pr-output.h" #include "utils.h" +#include "variables.h" -static SVD::driver driver = SVD::GESVD; +static int Vsvd_driver = SVD::GESVD; DEFUN_DLD (svd, args, nargout, "-*- texinfo -*-\n\ @@ -148,6 +149,9 @@ ? SVD::sigma_only : (nargin == 2) ? SVD::economy : SVD::std); + SVD::driver driver = static_cast (Vsvd_driver); + assert (driver == SVD::GESVD || driver == SVD::GESDD); + if (nr == 0 || nc == 0) { if (isfloat) @@ -399,7 +403,7 @@ */ -DEFUN_DLD (svd_driver, args, , +DEFUN_DLD (svd_driver, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{old} =} svd_driver (@var{new})\n\ Sets or queries the underlying LAPACK driver used by svd.\n\ @@ -407,34 +411,7 @@ @seealso{svd}\n\ @end deftypefn") { - octave_value retval; - int nargin = args.length (); - - if (nargin == 0 || (nargin == 1 && args(0).is_string ())) - { - if (driver == SVD::GESVD) - retval = "gesvd"; - else if (driver == SVD::GESDD) - retval = "gesdd"; - else - panic_impossible (); - + static const char *driver_names[] = { "gesvd", "gesdd" }; - if (nargin == 1) - { - std::string opt = args(0).xtolower ().string_value (); - if (opt == "gesvd") - driver = SVD::GESVD; - else if (opt == "gesdd") - driver = SVD::GESDD; - else - error ("svd_driver: invalid driver spec: %s", opt.c_str ()); - } - } - else - print_usage (); - - return retval; + return SET_INTERNAL_VARIABLE_CHOICES (svd_driver, driver_names); } - - diff --git a/src/variables.cc b/src/variables.cc --- a/src/variables.cc +++ b/src/variables.cc @@ -871,6 +871,52 @@ return retval; } +octave_value +set_internal_variable (int& var, const octave_value_list& args, + int nargout, const char *nm, const char **choices, + int nchoices) +{ + octave_value retval; + + int nargin = args.length (); + assert (var < nchoices); + + if (nargout > 0 || nargin == 0) + retval = choices[var]; + + if (wants_local_change (args, nargin)) + { + if (! try_local_protect (var)) + warning ("\"local\" has no effect outside a function"); + } + + if (nargin == 1) + { + std::string sval = args(0).string_value (); + + if (! error_state) + { + int i = 0; + for (; i < nchoices; i++) + { + if (sval == choices[i]) + { + var = i; + break; + } + } + if (i == nchoices) + error ("%s: value not allowed (\"%s\")", nm, sval.c_str ()); + } + else + error ("%s: expecting arg to be a character string", nm); + } + else if (nargin > 1) + print_usage (); + + return retval; +} + struct whos_parameter { diff --git a/src/variables.h b/src/variables.h --- a/src/variables.h +++ b/src/variables.h @@ -109,6 +109,11 @@ set_internal_variable (std::string& var, const octave_value_list& args, int nargout, const char *nm, bool empty_ok = true); +extern OCTINTERP_API octave_value +set_internal_variable (int& var, const octave_value_list& args, + int nargout, const char *nm, const char **choices, + int nchoices); + #define SET_INTERNAL_VARIABLE(NM) \ set_internal_variable (V ## NM, args, nargout, #NM) @@ -118,6 +123,11 @@ #define SET_INTERNAL_VARIABLE_WITH_LIMITS(NM, MINVAL, MAXVAL) \ set_internal_variable (V ## NM, args, nargout, #NM, MINVAL, MAXVAL) +// in the following, CHOICES must be a static C string array. +#define SET_INTERNAL_VARIABLE_CHOICES(NM, CHOICES) \ + set_internal_variable (V ## NM, args, nargout, #NM, CHOICES, \ + sizeof (CHOICES) / sizeof (const char *)) + extern OCTINTERP_API std::string builtin_string_variable (const std::string&); extern OCTINTERP_API int builtin_real_scalar_variable (const std::string&, double&); extern OCTINTERP_API octave_value builtin_any_variable (const std::string&);