Mercurial > octave
changeset 30304:b568c29bb5be
Add support for "class" option to exist() function (bug #46260)
* variables.cc (symbol_exist): Add support for "class" input by checking symbol
table for function which for which is_classdef_meta () returns true.
* variables.cc (Fexist): Update documentation to describe support for "class"
input type. Remove warning emitted when "class" type used. Update BIST tests.
author | Rik <rik@octave.org> |
---|---|
date | Fri, 19 Nov 2021 20:57:09 -0800 |
parents | cd63a97cb9be |
children | c13204f823a6 |
files | libinterp/corefcn/variables.cc |
diffstat | 1 files changed, 37 insertions(+), 34 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/variables.cc Fri Nov 19 08:04:45 2021 -0500 +++ b/libinterp/corefcn/variables.cc Fri Nov 19 20:57:09 2021 -0800 @@ -176,8 +176,6 @@ || search_builtin || search_class)) error (R"(exist: unrecognized type argument "%s")", type.c_str ()); - symbol_table& symtab = interp.get_symbol_table (); - if (search_any || search_var) { octave_value val = interp.varval (name); @@ -192,10 +190,12 @@ return 0; } + symbol_table& symtab = interp.get_symbol_table (); + // We shouldn't need to look in the global symbol table, since any name // that is visible in the current scope will be in the local symbol table. - if (search_any || search_file || search_dir) + if (search_any || search_file || search_dir || search_class) { bool have_fcn_ext = false; @@ -217,15 +217,16 @@ std::string file_name; - if (search_any || search_file) + if (search_any || search_file || search_class) { load_path& lp = interp.get_load_path (); - // Class constructor. + // Look for class constructor first file_name = lp.find_method (xname, xname); if (have_fcn_ext && ! file_name.empty ()) { + // Verify extension of file_name found matches ext of name. pos = file_name.rfind ('.'); if (pos != std::string::npos) @@ -247,7 +248,6 @@ } // Autoloads can only have simple names without extensions. - if (! have_fcn_ext && file_name.empty ()) { tree_evaluator& tw = interp.get_evaluator (); @@ -255,26 +255,35 @@ file_name = tw.lookup_autoload (name); } - // Use original name here. - + // If nothing found, look for function using original name. if (file_name.empty ()) file_name = lp.find_fcn (name); } std::size_t len = file_name.length (); - if (len > 0) + if (len > 0 && (search_any || search_file || search_class)) { if (search_any || search_file) { if (len > 4 && (file_name.substr (len-4) == ".oct" || file_name.substr (len-4) == ".mex")) return 3; + } + + if (search_class) + { + octave_value oval = symtab.find_function (name); + if (oval.is_defined () && oval.is_classdef_meta ()) + return 8; else - return 2; + return 0; } + + return 2; } + // Nothing found in symbol table, try searching in path file_name = file_in_path (name, ""); if (file_name.empty ()) @@ -379,7 +388,7 @@ @var{name} is a directory. @item 8 -@var{name} is a class. (Note: not currently implemented) +@var{name} is a classdef class. @item 103 @var{name} is a function not associated with a file (entered on the command @@ -406,8 +415,7 @@ Check only for files and directories. @item @qcode{"class"} -Check only for classes. (Note: This option is accepted, but not currently -implemented) +Check only for classdef classes. @end table If no type is given, and there are multiple possible matches for name, @@ -433,13 +441,11 @@ // For compatibility with undocumented Matlab behavior, return 0 if // there is an empty built-in object as the only argument. - if (args(0).builtin_type () != btyp_unknown && args(0).isempty ()) return ovl (0); // Also for compatibility, return 0 if the second argument is an empty // built-in object. - if (nargin == 2 && args(1).builtin_type () != btyp_unknown && args(1).isempty ()) return ovl (0); @@ -451,9 +457,6 @@ std::string type = args(1).xstring_value ("exist: TYPE must be a string"); - if (type == "class") - warning (R"(exist: "class" type argument is not implemented)"); - return ovl (symbol_exist (interp, name, type)); } else @@ -471,16 +474,15 @@ %!assert (exist ("__var1", "builtin"), 0) %!assert (exist ("__var1", "dir"), 0) %!assert (exist ("__var1", "file"), 0) +%!assert (exist ("__var1", "class"), 0) -%!test -%! if (isunix ()) -%! assert (exist ("/bin/sh"), 2); -%! assert (exist ("/bin/sh", "file"), 2); -%! assert (exist ("/bin/sh", "dir"), 0); -%! assert (exist ("/dev/null"), 2); -%! assert (exist ("/dev/null", "file"), 2); -%! assert (exist ("/dev/null", "dir"), 0); -%! endif +%!testif ; isunix () +%! assert (exist ("/bin/sh"), 2); +%! assert (exist ("/bin/sh", "file"), 2); +%! assert (exist ("/bin/sh", "dir"), 0); +%! assert (exist ("/dev/null"), 2); +%! assert (exist ("/dev/null", "file"), 2); +%! assert (exist ("/dev/null", "dir"), 0); %!assert (exist ("print_usage"), 2) %!assert (exist ("print_usage.m"), 2) @@ -512,13 +514,15 @@ %!assert (exist ("fftw", "file"), 3) %!assert (exist ("fftw", "builtin"), 0) -%!assert (exist ("ftp"), 2); -%!assert (exist ("ftp.m"), 2); -%!assert (exist ("@ftp/ftp"), 2); -%!assert (exist ("@ftp/ftp.m"), 2); +%!assert (exist ("ftp"), 2) +%!assert (exist ("ftp.m"), 2) +%!assert (exist ("@ftp/ftp"), 2) +%!assert (exist ("@ftp/ftp.m"), 2) +%!assert (exist ("ftp", "class"), 0) -%!assert (exist ("inputParser"), 2); -%!assert (exist ("inputParser.m"), 2); +%!assert (exist ("inputParser"), 2) +%!assert (exist ("inputParser.m"), 2) +%!assert (exist ("inputParser", "class"), 8) %!assert (exist ("sin"), 5) %!assert (exist ("sin", "builtin"), 5) @@ -530,7 +534,6 @@ %!error exist () %!error exist (1,2,3) -%!warning <"class" type argument is not implemented> exist ("a", "class"); %!error <TYPE must be a string> exist ("a", 1) %!error <NAME must be a string> exist (1) %!error <unrecognized type argument "foobar"> exist ("a", "foobar")