Mercurial > octave
changeset 28710:68c792e54d19
check and mark private status when reloading functions (bug #40117)
* fcn-info.cc (load_out_of_date_fcn): Look at function location to
determine private status and class membership. Store status in loaded
function.
* test/bug-40117.tst: New file.
* test/module.mk: Update.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Thu, 10 Sep 2020 11:36:50 -0400 |
parents | 9dc9f15dac64 |
children | e8b7863a7e6b |
files | libinterp/corefcn/fcn-info.cc test/bug-40117.tst test/module.mk |
diffstat | 3 files changed, 117 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/fcn-info.cc Thu Sep 10 17:49:43 2020 +0200 +++ b/libinterp/corefcn/fcn-info.cc Thu Sep 10 11:36:50 2020 -0400 @@ -409,21 +409,59 @@ // would not check for it when finding symbol definitions. static inline bool - load_out_of_date_fcn (const std::string& ff, const std::string& dir_name, + load_out_of_date_fcn (const std::string& file_name, + const std::string& dir_name_arg, octave_value& function, const std::string& dispatch_type = "", const std::string& package_name = "") { bool retval = false; + std::string dir_name = dir_name_arg; + + if (dir_name.empty ()) + { + size_t pos = file_name.find_last_of (sys::file_ops::dir_sep_chars ()); + + dir_name = file_name.substr (0, pos); + } + + // FIXME: do the following job of determining private status and + // class membership in a separate function? + + size_t pos = dir_name.find_last_of (sys::file_ops::dir_sep_chars ()); + + bool is_private_fcn + = pos != std::string::npos && dir_name.substr (pos+1) == "private"; + + if (is_private_fcn) + dir_name = dir_name.substr (0, pos); + + std::string class_name; + + pos = dir_name.find_last_of (sys::file_ops::dir_sep_chars ()); + + if (pos != std::string::npos) + { + std::string tmp = dir_name.substr (pos+1); + + if (tmp[0] == '@') + class_name = tmp.substr (1); + } + octave_value ov_fcn - = load_fcn_from_file (ff, dir_name, dispatch_type, + = load_fcn_from_file (file_name, dir_name, dispatch_type, package_name); if (ov_fcn.is_defined ()) { retval = true; + octave_function *fcn = ov_fcn.function_value (); + + if (is_private_fcn) + fcn->mark_as_private_function (class_name); + function = ov_fcn; } else
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/bug-40117.tst Thu Sep 10 11:36:50 2020 -0400 @@ -0,0 +1,76 @@ +######################################################################## +## +## Copyright (C) 2020 The Octave Project Developers +## +## See the file COPYRIGHT.md in the top-level directory of this +## distribution or <https://octave.org/copyright/>. +## +## This file is part of Octave. +## +## Octave is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <https://www.gnu.org/licenses/>. +## +######################################################################## + +%!function __mktestfun_40117__ (file, varargin) +%! unwind_protect +%! fid = fopen (file, "w"); +%! fprintf (fid, "%s\n", varargin{:}); +%! unwind_protect_cleanup +%! if (fid > 0) +%! fclose (fid); +%! endif +%! end_unwind_protect +%!endfunction + +%!test <40117> +%! unwind_protect +%! tmp_dir = tempname (); +%! mkdir (tmp_dir); +%! a_dir = fullfile (tmp_dir, "a"); +%! a_private_dir = fullfile (a_dir, "private"); +%! mkdir (a_dir); +%! mkdir (a_private_dir); +%! __mktestfun_40117__ (fullfile (a_dir, "main_40117.m"), +%! "function r = main_40117 ()", +%! " r = p1_40117 ();", +%! "endfunction"); +%! __mktestfun_40117__ (fullfile (a_private_dir, "p1_40117.m"), +%! "function r = p1_40117 ()", +%! " r = p2_40117 ();", +%! "endfunction"); +%! __mktestfun_40117__ (fullfile (a_private_dir, "p2_40117.m"), +%! "function r = p2_40117 ()", +%! " r = 'a_p2_40117';", +%! "endfunction"); +%! addpath (a_dir); +%! assert (main_40117 (), "a_p2_40117"); +%! +%! ## Update the secondary private function, attempting to avoid +%! ## filesystem timestamp resolution problems. +%! pause (1); +%! __mktestfun_40117__ (fullfile (a_private_dir, "p2_40117.m"), +%! "function r = p2_40117 ()", +%! " r = 'new function!';", +%! "endfunction"); +%! +%! ## Force new functions to be found. +%! rehash (); +%! +%! assert (main_40117 (), "new function!"); +%! unwind_protect_cleanup +%! rmpath (a_dir); +%! confirm_recursive_rmdir (false, "local"); +%! rmdir (tmp_dir, "s"); +%! end_unwind_protect