Mercurial > octave
view libinterp/octave-value/cdef-property.cc @ 30244:4fe897f5db8e
print_usage.m: Fix error on invalid texinfo (bug #61363).
* scripts/help/print_usage.m (get_usage_texinfo): Do not call __makeinfo__ if
help string doesn't contain a @def* macro.
author | Markus Mützel <markus.muetzel@gmx.de> |
---|---|
date | Thu, 21 Oct 2021 16:42:38 +0200 |
parents | aef9c5caedcd |
children | 796f54d4ddbf |
line wrap: on
line source
//////////////////////////////////////////////////////////////////////// // // Copyright (C) 2012-2021 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/>. // //////////////////////////////////////////////////////////////////////// #if defined (HAVE_CONFIG_H) # include "config.h" #endif #include <algorithm> #include <iomanip> #include "cdef-class.h" #include "cdef-manager.h" #include "cdef-utils.h" #include "errwarn.h" #include "interpreter-private.h" #include "interpreter.h" #include "load-path.h" #include "ov-builtin.h" #include "ov-classdef.h" #include "ov-fcn-handle.h" #include "ov-usr-fcn.h" #include "parse.h" #include "pt-assign.h" #include "pt-classdef.h" #include "pt-eval.h" #include "pt-idx.h" #include "pt-misc.h" #include "pt-stmt.h" #include "pt-walk.h" namespace octave { static bool is_method_executing (const octave_value& ov, const cdef_object& obj) { tree_evaluator& tw = __get_evaluator__ ("is_method_executing"); octave_function *stack_fcn = tw.current_function (); octave_function *method_fcn = ov.function_value (true); // Does the top of the call stack match our target function? if (stack_fcn && stack_fcn == method_fcn) { octave_user_function *uf = method_fcn->user_function_value (true); // We can only check the context object for user-function (not builtin), // where we have access to the parameters (arguments and return values). // That's ok as there's no need to call this function for builtin // methods. if (uf) { // At this point, the method is executing, but we still need to // check the context object for which the method is executing. For // methods, it's the first argument of the function; for ctors, it // is the first return value. tree_parameter_list *pl = uf->is_classdef_constructor () ? uf->return_list () : uf->parameter_list (); if (pl && pl->size () > 0) { tree_decl_elt *elt = pl->front (); octave_value arg0 = tw.evaluate (elt); if (arg0.is_defined () && arg0.type_name () == "object") { cdef_object arg0_obj = to_cdef (arg0); return obj.is (arg0_obj); } } } } return false; } octave_value cdef_property::cdef_property_rep::get_value (const cdef_object& obj, bool do_check_access, const std::string& who) const { octave_value retval; if (do_check_access && ! check_get_access ()) err_property_access (who, false); if (! obj.is_constructed ()) { cdef_class cls (to_cdef (get ("DefiningClass"))); if (! obj.is_partially_constructed_for (cls)) error ("cannot reference properties of class '%s' for non-constructed object", cls.get_name ().c_str ()); } octave_value get_fcn = get ("GetMethod"); // FIXME: should check whether we're already in get accessor method if (get_fcn.isempty () || is_method_executing (get_fcn, obj)) retval = obj.get (get ("Name").string_value ()); else { octave_value_list args; args(0) = to_ov (obj); args = feval (get_fcn, args, 1); retval = args(0); } return retval; } octave_value cdef_property::cdef_property_rep::get_value (bool do_check_access, const std::string& who) const { if (do_check_access && ! check_get_access ()) err_property_access (who, false); return get ("DefaultValue"); } bool cdef_property::cdef_property_rep::is_recursive_set (const cdef_object& /* obj */) const { // FIXME: implement return false; } OCTAVE_NORETURN void cdef_property::cdef_property_rep::err_property_access (const std::string& from, bool is_set) const { octave_value acc = get (is_set ? "SetAccess" : "GetAccess"); std::string acc_s; if (acc.is_string ()) acc_s = acc.string_value (); else acc_s = "class-restricted"; if (is_set) error ("%s: property '%s' has %s access and cannot be set in this context", from.c_str (), get_name ().c_str (), acc_s.c_str ()); else error ("%s: property '%s' has %s access and cannot be obtained in this context", from.c_str (), get_name ().c_str (), acc_s.c_str ()); } void cdef_property::cdef_property_rep::set_value (cdef_object& obj, const octave_value& val, bool do_check_access, const std::string& who) { if (do_check_access && ! check_set_access ()) err_property_access (who, true); if (! obj.is_constructed ()) { cdef_class cls (to_cdef (get ("DefiningClass"))); if (! obj.is_partially_constructed_for (cls)) error ("cannot reference properties of class '%s' for non-constructed object", cls.get_name ().c_str ()); } octave_value set_fcn = get ("SetMethod"); if (set_fcn.isempty () || is_method_executing (set_fcn, obj)) obj.put (get ("Name").string_value (), val); else { octave_value_list args; args(0) = to_ov (obj); args(1) = val; if (obj.is_handle_object ()) feval (set_fcn, args, 0); else { args = feval (set_fcn, args, 1); if (args.length () > 0 && args(0).is_defined ()) { if (args(0).is_classdef_object ()) { cdef_object new_obj = to_cdef (args(0)); obj = new_obj; } else ::warning ("set-method of property '%s' returned a non-classdef object", get_name ().c_str ()); } } } } bool cdef_property::cdef_property_rep::check_get_access (void) const { cdef_class cls (to_cdef (get ("DefiningClass"))); return check_access (cls, get ("GetAccess"), "", get_name (), false); return false; } bool cdef_property::cdef_property_rep::check_set_access (void) const { cdef_class cls (to_cdef (get ("DefiningClass"))); return check_access (cls, get ("SetAccess"), "", get_name (), true); return false; } }