GNU Octave  8.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
cdef-method.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2012-2023 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include <algorithm>
31 #include <iomanip>
32 
33 #include "cdef-class.h"
34 #include "cdef-manager.h"
35 #include "cdef-utils.h"
36 #include "errwarn.h"
37 #include "interpreter-private.h"
38 #include "interpreter.h"
39 #include "load-path.h"
40 #include "ov-builtin.h"
41 #include "ov-classdef.h"
42 #include "ov-fcn-handle.h"
43 #include "ov-usr-fcn.h"
44 #include "parse.h"
45 #include "pt-assign.h"
46 #include "pt-classdef.h"
47 #include "pt-idx.h"
48 #include "pt-misc.h"
49 #include "pt-stmt.h"
50 #include "pt-walk.h"
51 
53 
54 OCTAVE_NORETURN static
55 void
56 err_method_access (const std::string& from, const cdef_method& meth)
57 {
58  octave_value acc = meth.get ("Access");
59  std::string acc_s;
60 
61  if (acc.is_string ())
62  acc_s = acc.string_value ();
63  else
64  acc_s = "class-restricted";
65 
66  error ("%s: method '%s' has %s access and cannot be run in this context",
67  from.c_str (), meth.get_name ().c_str (), acc_s.c_str ());
68 }
69 
70 void
72 {
73  if (is_external ())
74  {
76  {
78 
79  std::string name = get_name ();
80  std::string cls_name = m_dispatch_type;
81  std::string pack_name;
82 
83  std::size_t pos = cls_name.rfind ('.');
84 
85  if (pos != std::string::npos)
86  {
87  pack_name = cls_name.substr (0, pos);
88  cls_name = cls_name.substr (pos + 1);
89  }
90 
91  std::string dir_name;
92  std::string file_name = lp.find_method (cls_name, name,
93  dir_name, pack_name);
94 
95  if (! file_name.empty ())
96  {
97  octave_value ov_fcn
98  = load_fcn_from_file (file_name, dir_name,
99  m_dispatch_type, pack_name);
100 
101  if (ov_fcn.is_defined ())
102  {
103  m_function = ov_fcn;
104 
106  }
107  }
108  }
109  else
110  {
111  // FIXME: check out-of-date status
112  }
113 
115  error ("no definition found for method '%s' of class '%s'",
116  get_name ().c_str (), m_dispatch_type.c_str ());
117  }
118 }
119 
122  int nargout, bool do_check_access,
123  const std::string& who)
124 {
125  octave_value_list retval;
126 
127  if (do_check_access && ! check_access ())
128  err_method_access (who, wrap ());
129 
130  if (get ("Abstract").bool_value ())
131  error ("%s: cannot execute abstract method",
132  get ("Name").string_value ().c_str ());
133 
134  check_method ();
135 
136  if (m_function.is_defined ())
137  retval = feval (m_function, args, nargout);
138 
139  return retval;
140 }
141 
144  const octave_value_list& args,
145  int nargout, bool do_check_access,
146  const std::string& who)
147 {
148  octave_value_list retval;
149 
150  if (do_check_access && ! check_access ())
151  err_method_access (who, wrap ());
152 
153  if (get ("Abstract").bool_value ())
154  error ("%s: cannot execute abstract method",
155  get ("Name").string_value ().c_str ());
156 
157  check_method ();
158 
159  if (m_function.is_defined ())
160  {
161  octave_value_list new_args;
162 
163  new_args.resize (args.length () + 1);
164 
165  new_args(0) = to_ov (obj);
166  for (int i = 0; i < args.length (); i++)
167  new_args(i+1) = args(i);
168 
169  retval = feval (m_function, new_args, nargout);
170  }
171 
172  return retval;
173 }
174 
175 bool
177 {
178  if (m_function.is_function())
179  return m_function.function_value ()->is_classdef_constructor ();
180 
181  return false;
182 }
183 
184 bool
186 {
187  return (m_function.is_function ()
188  ? m_function.function_value ()->dispatch_class () == cname
189  : false);
190 }
191 
192 std::string
194 {
195  check_method ();
196 
197  octave_function *fcn = m_function.function_value ();
198 
199  return fcn ? fcn->doc_string () : "";
200 }
201 
202 bool
204 {
205  cdef_class cls (to_cdef (get ("DefiningClass")));
206 
207  return octave::check_access (cls, get ("Access"), get_name ());
208 }
209 
212 (const std::string& type, const std::list<octave_value_list>& idx,
213  int nargout)
214 {
215  octave_value_list retval;
216 
217  switch (type[0])
218  {
219  case '(':
220  retval = (execute (idx.front (),
221  type.length () > 1 ? 1 : nargout, true));
222  break;
223 
224  default:
225  error ("invalid meta.method indexing");
226  break;
227  }
228 
229  if (type.length () > 1 && idx.size () > 1 && ! retval.empty ())
230  retval = retval(0).next_subsref (nargout, type, idx, 1);
231 
232  return retval;
233 }
234 
OCTAVE_END_NAMESPACE(octave)
static OCTAVE_NORETURN void err_method_access(const std::string &from, const cdef_method &meth)
Definition: cdef-method.cc:56
bool check_access(const cdef_class &cls, const octave_value &acc, const std::string &meth_name, const std::string &prop_name, bool is_prop_set)
Definition: cdef-utils.cc:294
bool is_dummy_method(const octave_value &fcn)
Definition: cdef-utils.cc:179
cdef_object to_cdef(const octave_value &val)
Definition: cdef-utils.cc:143
octave_value to_ov(const cdef_object &obj)
Definition: cdef-utils.cc:128
void make_function_of_class(const std::string &class_name, const octave_value &fcn)
Definition: cdef-utils.cc:55
OCTINTERP_API bool check_access(void) const
Definition: cdef-method.cc:203
OCTINTERP_API bool is_constructor(void) const
Definition: cdef-method.cc:176
OCTINTERP_API std::string get_doc_string(void)
Definition: cdef-method.cc:193
OCTINTERP_API void check_method(void)
Definition: cdef-method.cc:71
OCTINTERP_API octave_value_list execute(const octave_value_list &args, int nargout, bool do_check_access=true, const std::string &who="")
Definition: cdef-method.cc:121
octave_value_list meta_subsref(const std::string &type, const std::list< octave_value_list > &idx, int nargout)
Definition: cdef-method.cc:212
bool is_external(void) const
Definition: cdef-method.h:81
std::string get_name(void) const
Definition: cdef-method.h:67
OCTINTERP_API bool is_defined_in_class(const std::string &cname) const
Definition: cdef-method.cc:185
octave_value_list execute(const octave_value_list &args, int nargout, bool do_check_access=true, const std::string &who="")
Definition: cdef-method.h:164
bool check_access(void) const
Definition: cdef-method.h:180
std::string get_name(void) const
Definition: cdef-method.h:182
octave_value get(const std::string &pname) const
Definition: cdef-object.h:268
std::string find_method(const std::string &class_name, const std::string &meth, std::string &dir_name, const std::string &pack_name="")
Definition: load-path.h:79
virtual octave_function * function_value(bool silent=false)
Definition: ov-base.cc:940
virtual std::string doc_string(const std::string &="") const
Definition: ov-fcn.h:221
bool empty(void) const
Definition: ovl.h:115
void resize(octave_idx_type n, const octave_value &rfv=octave_value())
Definition: ovl.h:117
octave_idx_type length(void) const
Definition: ovl.h:113
bool is_string(void) const
Definition: ov.h:682
bool is_defined(void) const
Definition: ov.h:637
std::string string_value(bool force=false) const
Definition: ov.h:1019
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
void error(const char *fmt,...)
Definition: error.cc:979
load_path & __get_load_path__(void)
octave_value load_fcn_from_file(const std::string &file_name, const std::string &dir_name, const std::string &dispatch_type, const std::string &package_name, const std::string &fcn_name, bool autoload)
Definition: oct-parse.cc:10117
octave_value_list feval(const char *name, const octave_value_list &args, int nargout)
Evaluate an Octave function (built-in or interpreted) and return the list of result values.
Definition: oct-parse.cc:10370