GNU Octave  4.2.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ov-classdef.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2012-2017 Michael Goffioul
4 
5 This file is part of Octave.
6 
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #if defined (HAVE_CONFIG_H)
24 # include "config.h"
25 #endif
26 
27 #include <algorithm>
28 
29 #include "call-stack.h"
30 #include "defun.h"
31 #include "load-path.h"
32 #include "ov-builtin.h"
33 #include "ov-classdef.h"
34 #include "ov-fcn-handle.h"
35 #include "ov-typeinfo.h"
36 #include "ov-usr-fcn.h"
37 #include "pt-assign.h"
38 #include "pt-classdef.h"
39 #include "pt-funcall.h"
40 #include "pt-misc.h"
41 #include "pt-stmt.h"
42 #include "pt-walk.h"
43 #include "singleton-cleanup.h"
44 #include "symtab.h"
45 #include "interpreter.h"
46 
47 // Define to 1 to enable debugging statements.
48 #define DEBUG_TRACE 0
49 
50 OCTAVE_NORETURN static
51 void
52 err_method_access (const std::string& from, const cdef_method& meth)
53 {
54  octave_value acc = meth.get ("Access");
55  std::string acc_s;
56 
57  if (acc.is_string ())
58  acc_s = acc.string_value ();
59  else
60  acc_s = "class-restricted";
61 
62  error ("%s: method `%s' has %s access and cannot be run in this context",
63  from.c_str (), meth.get_name ().c_str (), acc_s.c_str ());
64 }
65 
66 OCTAVE_NORETURN static
67 void
68 err_property_access (const std::string& from, const cdef_property& prop,
69  bool is_set = false)
70 {
71  octave_value acc = prop.get (is_set ? "SetAccess" : "GetAccess");
72  std::string acc_s;
73 
74  if (acc.is_string ())
75  acc_s = acc.string_value ();
76  else
77  acc_s = "class-restricted";
78 
79  if (is_set)
80  error ("%s: property `%s' has %s access and cannot be set in this context",
81  from.c_str (), prop.get_name ().c_str (), acc_s.c_str ());
82  else
83  error ("%s: property `%s' has %s access and cannot be obtained in this context",
84  from.c_str (), prop.get_name ().c_str (), acc_s.c_str ());
85 }
86 
87 static std::string
89 {
90  std::string::size_type pos = nm.find_last_of ('.');
91 
92  if (pos != std::string::npos)
93  return nm.substr (pos + 1);
94 
95  return nm;
96 }
97 
98 static void
100  const octave_value& fcn)
101 {
103 
104  of->stash_dispatch_class (class_name);
105 
106  octave_user_function *uf = of->user_function_value (true);
107 
108  if (uf)
109  {
110  if (get_base_name (class_name) == uf->name ())
111  {
114  }
115  else
116  uf->mark_as_class_method ();
117  }
118 }
119 
120 static void
122 {
124 }
125 
126 static octave_value
128 {
129  octave_value fcn (new octave_builtin (ff, nm));
130 
131  octave_value fcn_handle (new octave_fcn_handle (fcn, nm));
132 
133  return fcn_handle;
134 }
135 
136 static octave_value
138 {
140 
141  if (fcn.is_defined ())
142  retval = octave_value (new octave_fcn_handle (fcn, nm));
143 
144  return retval;
145 }
146 
147 inline octave_value_list
149 {
150  std::list<octave_value_list> idx (1, args);
151 
152  std::string type ("(");
153 
154  return val.subsref (type, idx, nargout);
155 }
156 
157 static cdef_class
158 lookup_class (const std::string& name, bool error_if_not_found = true,
159  bool load_if_not_found = true)
160 {
161  return cdef_manager::find_class (name, error_if_not_found,
162  load_if_not_found);
163 }
164 
165 static cdef_class
167 {
168  // FIXME: placeholder for the time being, the purpose
169  // is to centralized any class update activity here.
170 
171  return cls;
172 }
173 
174 static cdef_class
176 {
177  if (ov.is_string())
178  return lookup_class (ov.string_value ());
179  else
180  {
181  cdef_class cls (to_cdef (ov));
182 
183  return lookup_class (cls);
184  }
185 
186  return cdef_class ();
187 }
188 
189 static std::list<cdef_class>
190 lookup_classes (const Cell& cls_list)
191 {
192  std::list<cdef_class> retval;
193 
194  for (int i = 0; i < cls_list.numel (); i++)
195  {
196  cdef_class c = lookup_class (cls_list(i));
197 
198  retval.push_back (c);
199  }
200 
201  return retval;
202 }
203 
204 static octave_value
205 to_ov (const std::list<cdef_class>& class_list)
206 {
207  Cell cls (class_list.size (), 1);
208  int i = 0;
209 
210  for (std::list<cdef_class>::const_iterator it = class_list.begin ();
211  it != class_list.end (); ++it, ++i)
212  cls(i) = to_ov (*it);
213 
214  return octave_value (cls);
215 }
216 
217 static bool
218 is_superclass (const cdef_class& clsa, const cdef_class& clsb,
219  bool allow_equal = true, int max_depth = -1)
220 {
221  bool retval = false;
222 
223  if (allow_equal && clsa == clsb)
224  retval = true;
225  else if (max_depth != 0)
226  {
227  Cell c = clsb.get ("SuperClasses").cell_value ();
228 
229  for (int i = 0; ! retval && i < c.numel (); i++)
230  {
231  cdef_class cls = lookup_class (c(i));
232 
233  retval = is_superclass (clsa, cls, true,
234  max_depth < 0 ? max_depth : max_depth-1);
235  }
236  }
237 
238  return retval;
239 }
240 
241 inline bool
242 is_strict_superclass (const cdef_class& clsa, const cdef_class& clsb)
243 { return is_superclass (clsa, clsb, false); }
244 
245 inline bool
246 is_direct_superclass (const cdef_class& clsa, const cdef_class& clsb)
247 { return is_superclass (clsa, clsb, false, 1); }
248 
249 static octave_value_list
250 class_get_properties (const octave_value_list& args, int /* nargout */)
251 {
253 
254  if (args.length () == 1 && args(0).type_name () == "object")
255  {
256  cdef_class cls (to_cdef (args(0)));
257 
258  retval(0) = cls.get_properties ();
259  }
260 
261  return retval;
262 }
263 
264 static cdef_class
265 get_class_context (std::string& name, bool& in_constructor)
266 {
267  cdef_class cls;
268 
270 
271  in_constructor = false;
272 
273  if (fcn && (fcn->is_class_method ()
274  || fcn->is_classdef_constructor ()
276  || (fcn->is_private_function ()
277  && ! fcn->dispatch_class ().empty ())))
278  {
279  cls = lookup_class (fcn->dispatch_class ());
280 
281  name = fcn->name ();
282  in_constructor = fcn->is_classdef_constructor ();
283  }
284 
285  return cls;
286 }
287 
288 inline cdef_class
290 {
291  std::string dummy_string;
292  bool dummy_bool;
293 
294  return get_class_context (dummy_string, dummy_bool);
295 }
296 
297 static bool
299 {
300  cdef_class ctx = get_class_context ();
301 
302  return (ctx.ok () && is_superclass (ctx, cls));
303 }
304 
305 static bool
306 check_access (const cdef_class& cls, const octave_value& acc,
307  const std::string& meth_name = "",
308  const std::string& prop_name = "",
309  bool is_prop_set = false)
310 {
311  if (acc.is_string ())
312  {
313  std::string acc_s = acc.string_value ();
314 
315  if (acc_s == "public")
316  return true;
317 
318  cdef_class ctx = get_class_context ();
319 
320  // The access is private or protected, this requires a
321  // valid class context.
322 
323  if (ctx.ok ())
324  {
325  if (acc_s == "private")
326  return (ctx == cls);
327  else if (acc_s == "protected")
328  {
329  if (is_superclass (cls, ctx))
330  // Calling a protected method in a superclass.
331  return true;
332  else if (is_strict_superclass (ctx, cls))
333  {
334  // Calling a protected method or property in a derived class.
335  // This is only allowed if the context class knows about it
336  // and has access to it.
337 
338  if (! meth_name.empty ())
339  {
340  cdef_method m = ctx.find_method (meth_name);
341 
342  if (m.ok ())
343  return check_access (ctx, m.get ("Access"), meth_name);
344 
345  return false;
346  }
347  else if (! prop_name.empty ())
348  {
349  cdef_property p = ctx.find_property (prop_name);
350 
351  if (p.ok ())
352  {
353  octave_value p_access = p.get (is_prop_set ?
354  "SetAccess" :
355  "GetAccess");
356 
357  return check_access (ctx, p_access, meth_name,
358  prop_name, is_prop_set);
359  }
360 
361  return false;
362  }
363  else
364  panic_impossible ();
365  }
366 
367  return false;
368  }
369  else
370  panic_impossible ();
371  }
372  }
373  else if (acc.is_cell ())
374  {
375  Cell acc_c = acc.cell_value ();
376 
377  cdef_class ctx = get_class_context ();
378 
379  // At this point, a class context is always required.
380 
381  if (ctx.ok ())
382  {
383  if (ctx == cls)
384  return true;
385 
386  for (int i = 0; i < acc.numel (); i++)
387  {
388  cdef_class acc_cls (to_cdef (acc_c(i)));
389 
390  if (is_superclass (acc_cls, ctx))
391  return true;
392  }
393  }
394  }
395  else
396  error ("invalid property/method access in class `%s'",
397  cls.get_name ().c_str ());
398 
399  return false;
400 }
401 
402 static bool
404 {
405  bool retval = false;
406 
407  if (fcn.is_defined ())
408  {
409  if (fcn.is_user_function ())
410  {
411  octave_user_function *uf = fcn.user_function_value (true);
412 
413  if (! uf || ! uf->body ())
414  retval = true;
415  }
416  }
417  else
418  retval = true;
419 
420  return retval;
421 }
422 
423 bool
425 {
427 
428  octave_function* method_fcn = ov.function_value (true);
429 
430  // Does the top of the call stack match our target function?
431 
432  if (stack_fcn && stack_fcn == method_fcn)
433  {
434  octave_user_function* uf = method_fcn->user_function_value (true);
435 
436  // We can only check the context object for user-function (not builtin),
437  // where we have access to the parameters (arguments and return values).
438  // That's ok as there's no need to call this function for builtin
439  // methods.
440 
441  if (uf)
442  {
443  // At this point, the method is executing, but we still need to
444  // check the context object for which the method is executing. For
445  // methods, it's the first argument of the function; for ctors, it
446  // is the first return value.
447 
449  ? uf->return_list () : uf->parameter_list ();
450 
451  if (pl && pl->size () > 0)
452  {
453  octave_value arg0 = pl->front ()->lvalue ().value ();
454 
455  if (arg0.is_defined () && arg0.type_name () == "object")
456  {
457  cdef_object arg0_obj = to_cdef (arg0);
458 
459  return obj.is (arg0_obj);
460  }
461  }
462  }
463  }
464 
465  return false;
466 }
467 
468 static octave_value_list
469 class_get_methods (const octave_value_list& args, int /* nargout */)
470 {
472 
473  if (args.length () == 1 && args(0).type_name () == "object")
474  {
475  cdef_class cls (to_cdef (args(0)));
476 
477  retval(0) = cls.get_methods ();
478  }
479 
480  return retval;
481 }
482 
483 static octave_value_list
484 class_get_superclasses (const octave_value_list& args, int /* nargout */)
485 {
487 
488  if (args.length () == 1 && args(0).type_name () == "object"
489  && args(0).class_name () == "meta.class")
490  {
491  cdef_class cls (to_cdef (args(0)));
492 
493  Cell classes = cls.get ("SuperClasses").cell_value ();
494 
495  retval(0) = to_ov (lookup_classes (classes));
496  }
497 
498  return retval;
499 }
500 
501 static octave_value_list
503 {
505 
506  if (args.length () == 1 && args(0).type_name () == "object"
507  && args(0).class_name () == "meta.class")
508  {
509  cdef_class cls (to_cdef (args(0)));
510 
511  Cell classes = cls.get ("InferiorClasses").cell_value ();
512 
513  retval(0) = to_ov (lookup_classes (classes));
514  }
515 
516  return retval;
517 }
518 
519 static octave_value_list
520 class_fromName (const octave_value_list& args, int /* nargout */)
521 {
523 
524  if (args.length () != 1)
525  error ("fromName: invalid number of parameters");
526 
527  std::string name = args(0).xstring_value ("fromName: CLASS_NAME must be a string");
528 
529  retval(0) = to_ov (lookup_class (name));
530 
531  return retval;
532 }
533 
534 static octave_value_list
536 {
537  if (args.length () <= 1 || args(0).type_name () != "object")
538  error ("fevalStatic: first argument must be a meta.class object");
539 
540  cdef_class cls (to_cdef (args(0)));
541 
542  std::string meth_name = args(1).xstring_value ("fevalStatic: method name must be a string");
543 
544  cdef_method meth = cls.find_method (meth_name);
545 
546  if (! meth.ok ())
547  error ("fevalStatic: method not found: %s", meth_name.c_str ());
548 
549  if (! meth.is_static ())
550  error ("fevalStatic: method `%s' is not static", meth_name.c_str ());
551 
552  return meth.execute (args.splice (0, 2), nargout, true, "fevalStatic");
553 }
554 
555 static octave_value_list
556 class_getConstant (const octave_value_list& args, int /* nargout */)
557 {
559 
560  if (args.length () != 2 || args(0).type_name () != "object"
561  || args(0).class_name () != "meta.class")
562  error ("getConstant: first argument must be a meta.class object");
563 
564  cdef_class cls = to_cdef (args(0));
565 
566  std::string prop_name = args(1).xstring_value ("getConstant: property name must be a string");
567 
568  cdef_property prop = cls.find_property (prop_name);
569 
570  if (! prop.ok ())
571  error ("getConstant: property not found: %s",
572  prop_name.c_str ());
573 
574  if (! prop.is_constant ())
575  error ("getConstant: property `%s' is not constant",
576  prop_name.c_str ());
577 
578  retval(0) = prop.get_value (true, "getConstant");
579 
580  return retval;
581 }
582 
583 #define META_CLASS_CMP(OP, CLSA, CLSB, FUN) \
584  static octave_value_list \
585  class_ ## OP (const octave_value_list& args, int /* nargout */) \
586  { \
587  octave_value_list retval; \
588  \
589  if (args.length () != 2 \
590  || args(0).type_name () != "object" \
591  || args(1).type_name () != "object" \
592  || args(0).class_name () != "meta.class" \
593  || args(1).class_name () != "meta.class") \
594  error (#OP ": invalid arguments"); \
595  \
596  cdef_class clsa = to_cdef (args(0)); \
597  \
598  cdef_class clsb = to_cdef (args(1)); \
599  \
600  retval(0) = FUN (CLSA, CLSB); \
601  \
602  return retval; \
603  }
604 
606 META_CLASS_CMP (le, clsb, clsa, is_superclass)
608 META_CLASS_CMP (ge, clsa, clsb, is_superclass)
609 META_CLASS_CMP (eq, clsa, clsb, operator==)
610 META_CLASS_CMP (ne, clsa, clsb, operator!=)
611 
614 {
616 
617  if (args.length () == 1 && args(0).type_name () == "object")
618  {
619  cdef_property prop (to_cdef (args(0)));
620 
621  retval(0) = prop.get ("DefaultValue");
622 
623  if (! retval(0).is_defined ())
624  error_with_id ("Octave:class:NotDefaultDefined",
625  "no default value for property `%s'",
626  prop.get_name ().c_str ());
627  }
628 
629  return retval;
630 }
631 
632 static octave_value_list
633 handle_delete (const octave_value_list& /* args */, int /* nargout */)
634 {
636 
637  // FIXME: implement this
638 
639  return retval;
640 }
641 
642 static cdef_class
644  const std::list<cdef_class>& super_list = std::list<cdef_class> ())
645 {
646  cdef_class cls (name, super_list);
647 
649  cls.put ("Abstract", false);
650  cls.put ("ConstructOnLoad", false);
651  cls.put ("ContainingPackage", Matrix ());
652  cls.put ("Description", "");
653  cls.put ("DetailedDescription", "");
654  cls.put ("Events", Cell ());
655  cls.put ("Hidden", false);
656  cls.put ("InferiorClasses", Cell ());
657  cls.put ("Methods", Cell ());
658  cls.put ("Properties", Cell ());
659  cls.put ("Sealed", false);
660 
661  if (name == "handle")
662  {
663  cls.put ("HandleCompatible", true);
664  cls.mark_as_handle_class ();
665  }
666  else if (super_list.empty ())
667  {
668  cls.put ("HandleCompatible", false);
669  }
670  else
671  {
672  bool all_handle_compatible = true;
673  bool has_handle_class = false;
674 
675  for (std::list<cdef_class>::const_iterator it = super_list.begin ();
676  it != super_list.end (); ++it)
677  {
678  all_handle_compatible = all_handle_compatible
679  && it->get ("HandleCompatible").bool_value ();
680  has_handle_class = has_handle_class || it->is_handle_class ();
681  }
682 
683  if (has_handle_class && ! all_handle_compatible)
684  error ("%s: cannot mix handle and non-HandleCompatible classes",
685  name.c_str ());
686 
687  cls.put ("HandleCompatible", all_handle_compatible);
688  if (has_handle_class)
689  cls.mark_as_handle_class ();
690  }
691 
692  if (! name.empty ())
694 
695  return cls;
696 }
697 
698 static cdef_class
699 make_class (const std::string& name, const cdef_class& super)
700 {
701  return make_class (name, std::list<cdef_class> (1, super));
702 }
703 
704 static cdef_class
705 make_meta_class (const std::string& name, const cdef_class& super)
706 {
707  cdef_class cls = make_class (name, super);
708 
709  cls.put ("Sealed", true);
710  cls.mark_as_meta_class ();
711 
712  return cls;
713 }
714 
715 static cdef_property
716 make_property (const cdef_class& cls, const std::string& name,
717  const octave_value& get_method = Matrix (),
718  const std::string& get_access = "public",
719  const octave_value& set_method = Matrix (),
720  const std::string& set_access = "public")
721 {
722  cdef_property prop (name);
723 
725  prop.put ("Description", "");
726  prop.put ("DetailedDescription", "");
727  prop.put ("Abstract", false);
728  prop.put ("Constant", false);
729  prop.put ("GetAccess", get_access);
730  prop.put ("SetAccess", set_access);
731  prop.put ("Dependent", false);
732  prop.put ("Transient", false);
733  prop.put ("Hidden", false);
734  prop.put ("GetObservable", false);
735  prop.put ("SetObservable", false);
736  prop.put ("GetMethod", get_method);
737  prop.put ("SetMethod", set_method);
738  prop.put ("DefiningClass", to_ov (cls));
739  prop.put ("DefaultValue", octave_value ());
740  prop.put ("HasDefault", false);
741 
742  std::string class_name = cls.get_name ();
743 
744  if (! get_method.is_empty ())
745  make_function_of_class (class_name, get_method);
746  if (! set_method.is_empty ())
747  make_function_of_class (class_name, set_method);
748 
749  return prop;
750 }
751 
752 inline cdef_property
753 make_attribute (const cdef_class& cls, const std::string& name)
754 {
755  return make_property (cls, name, Matrix (), "public", Matrix (), "private");
756 }
757 
758 static cdef_method
759 make_method (const cdef_class& cls, const std::string& name,
760  const octave_value& fcn,const std::string& m_access = "public",
761  bool is_static = false)
762 {
763  cdef_method meth (name);
764 
766  meth.put ("Abstract", false);
767  meth.put ("Access", m_access);
768  meth.put ("DefiningClass", to_ov (cls));
769  meth.put ("Description", "");
770  meth.put ("DetailedDescription", "");
771  meth.put ("Hidden", false);
772  meth.put ("Sealed", true);
773  meth.put ("Static", is_static);
774 
775  if (fcn.is_defined ())
776  make_function_of_class (cls, fcn);
777 
778  meth.set_function (fcn);
779 
780  if (is_dummy_method (fcn))
781  meth.mark_as_external (cls.get_name ());
782 
783  return meth;
784 }
785 
786 inline cdef_method
787 make_method (const cdef_class& cls, const std::string& name,
788  octave_builtin::fcn ff, const std::string& m_access = "public",
789  bool is_static = false)
790 {
791  octave_value fcn (new octave_builtin (ff, name));
792 
793  return make_method (cls, name, fcn, m_access, is_static);
794 }
795 
796 static cdef_package
798  const std::string& parent = "")
799 {
800  cdef_package pack (nm);
801 
803  if (parent.empty ())
804  pack.put ("ContainingPackage", Matrix ());
805  else
806  pack.put ("ContainingPackage", to_ov (cdef_manager::find_package (parent)));
807 
808  if (! nm.empty ())
810 
811  return pack;
812 }
813 
814 //----------------------------------------------------------------------------
815 
816 int octave_classdef::t_id (-1);
817 
818 const std::string octave_classdef::t_name ("object");
819 
820 void
822 {
824  (octave_classdef::t_name, "<unknown>",
825  octave_value (new octave_classdef ()));
826 }
827 
830  const std::list<octave_value_list>& idx,
831  int nargout)
832 {
833  size_t skip = 0;
835 
836  cdef_class cls = object.get_class ();
837 
838  if (! in_class_method (cls) && ! called_from_builtin ())
839  {
840  cdef_method meth = cls.find_method ("subsref");
841 
842  if (meth.ok ())
843  {
845 
846  args(1) = make_idx_args (type, idx, "subsref");
847 
848  count++;
849  args(0) = octave_value (this);
850 
851  retval = meth.execute (args, nargout, true, "subsref");
852 
853  return retval;
854  }
855  }
856 
857  // At this point, the default subsref mechanism must be used.
858 
859  retval = object.subsref (type, idx, nargout, skip, cdef_class ());
860 
861  if (type.length () > skip && idx.size () > skip)
862  retval = retval(0).next_subsref (nargout, type, idx, skip);
863 
864  return retval;
865 }
866 
869  const std::list<octave_value_list>& idx,
870  bool auto_add)
871 {
872  size_t skip = 0;
874 
875  // This variant of subsref is used to create temporary values when doing
876  // assignment with multi-level indexing. AFAIK this is only used for internal
877  // purpose (not sure we should even implement this) and any overload subsref
878  // should not be called.
879 
880  retval = object.subsref (type, idx, 1, skip, cdef_class (), auto_add);
881 
882  if (type.length () > skip && idx.size () > skip)
883  retval = retval(0).next_subsref (1, type, idx, skip);
884 
885  return retval.length () > 0 ? retval(0) : octave_value ();
886 }
887 
890  const std::list<octave_value_list>& idx,
891  const octave_value& rhs)
892 {
894 
895  cdef_class cls = object.get_class ();
896 
897  if (! in_class_method (cls) && ! called_from_builtin ())
898  {
899  cdef_method meth = cls.find_method ("subsasgn");
900 
901  if (meth.ok ())
902  {
904 
905  args(1) = make_idx_args (type, idx, "subsasgn");
906 
907  count++;
908  args(0) = octave_value (this);
909  args(2) = rhs;
910 
911  octave_value_list retlist;
912 
913  retlist = meth.execute (args, 1, true, "subsasgn");
914 
915  if (retlist.empty ())
916  error ("overloaded method `subsasgn' did not return any value");
917 
918  retval = retlist(0);
919  }
920  }
921 
922  if (! retval.is_defined ())
923  retval = object.subsasgn (type, idx, rhs);
924 
925  return retval;
926 }
927 
930  const std::list<octave_value_list>& idx,
931  const octave_value& rhs)
932 {
933  if (type.length () == 1 && type[0] == '(')
934  {
935  object = object.make_array ();
936 
937  return subsasgn (type, idx, rhs);
938  }
939  else
940  return octave_base_value::undef_subsasgn (type, idx, rhs);
941 
942  return octave_value ();
943 }
944 
945 void
946 octave_classdef::print (std::ostream& os, bool)
947 {
948  if (! called_from_builtin ())
949  {
950  cdef_method meth = object.get_class ().find_method ("disp");
951 
952  if (meth.ok ())
953  {
955 
956  count++;
957  args(0) = octave_value (this);
958 
959  indent (os);
960  meth.execute (args, 0, true, "disp");
961 
962  return;
963  }
964  }
965 
966  print_raw (os);
967 }
968 
969 void
970 octave_classdef::print_raw (std::ostream& os, bool) const
971 {
972  indent (os);
973  os << "<object ";
974  if (object.is_array ())
975  os << "array ";
976  os << class_name () << ">";
977  newline (os);
978 }
979 
980 bool
982  const std::string& name) const
983 {
984  return octave_base_value::print_name_tag (os, name);
985 }
986 
987 void
988 octave_classdef::print_with_name (std::ostream& os, const std::string& name,
989  bool print_padding)
990 {
991  cdef_method meth = object.get_class ().find_method ("display");
992 
993  if (meth.ok ())
994  {
996 
997  count++;
998  args(0) = octave_value (this);
999 
1000  string_vector arg_names (1);
1001 
1002  arg_names[0] = name;
1003  args.stash_name_tags (arg_names);
1004 
1005  indent (os);
1006  meth.execute (args, 0, true, "display");
1007  }
1008  else
1009  octave_base_value::print_with_name (os, name, print_padding);
1010 }
1011 
1012 bool
1014 {
1015  cdef_class cls = lookup_class (cls_name, false, false);
1016 
1017  if (cls.ok ())
1018  return is_superclass (cls, object.get_class ());
1019 
1020  return false;
1021 }
1022 
1023 //----------------------------------------------------------------------------
1024 
1026 {
1027 public:
1029  : object (obj) { }
1030 
1032  { object.meta_release (); }
1033 
1034  octave_function* function_value (bool = false) { return this; }
1035 
1038  const std::list<octave_value_list>& idx,
1039  int nargout)
1040  { return object.meta_subsref (type, idx, nargout); }
1041 
1042  octave_value
1044  const std::list<octave_value_list>& idx)
1045  {
1047 
1048  retval = subsref (type, idx, 1);
1049 
1050  return (retval.length () > 0 ? retval(0) : octave_value ());
1051  }
1052 
1055  {
1056  // Emulate ()-type meta subsref
1057 
1058  std::list<octave_value_list> l (1, idx);
1059  std::string type ("(");
1060 
1061  return subsref (type, l, nargout);
1062  }
1063 
1064  bool is_postfix_index_handled (char type) const
1065  { return object.meta_is_postfix_index_handled (type); }
1066 
1067  bool
1068  is_classdef_constructor (const std::string& cname = "") const
1069  {
1070  bool retval = false;
1071 
1072  if (object.is_class ())
1073  {
1074  if (cname.empty ())
1075  retval = true;
1076  else
1077  {
1078  cdef_class cls (object);
1079 
1080  if (cls.get_name () == cname)
1081  retval = true;
1082  }
1083  }
1084 
1085  return retval;
1086  }
1087 
1088 private:
1090 };
1091 
1092 //----------------------------------------------------------------------------
1093 
1095 {
1096 public:
1098  : octave_function (), args (a) { }
1099 
1101 
1102  octave_function* function_value (bool = false) { return this; }
1103 
1106  const std::list<octave_value_list>& idx,
1107  int nargout)
1108  {
1109  size_t skip = 0;
1111 
1112  switch (type[0])
1113  {
1114  case '(':
1115  skip = 1;
1116  retval = do_multi_index_op (type.length () > 1 ? 1 : nargout,
1117  idx.front ());
1118  break;
1119  default:
1120  retval = do_multi_index_op (1, octave_value_list ());
1121  break;
1122  }
1123 
1124  if (type.length () > skip && idx.size () > skip
1125  && retval.length () > 0)
1126  retval = retval(0).next_subsref (nargout, type, idx, skip);
1127 
1128  return retval;
1129  }
1130 
1131  octave_value
1133  const std::list<octave_value_list>& idx)
1134  {
1136 
1137  retval = subsref (type, idx, 1);
1138 
1139  return (retval.length () > 0 ? retval(0) : octave_value ());
1140  }
1141 
1144  {
1146 
1147  std::string meth_name;
1148  bool in_constructor;
1149  cdef_class ctx;
1150 
1151  ctx = get_class_context (meth_name, in_constructor);
1152 
1153  if (! ctx.ok ())
1154  error ("superclass calls can only occur in methods or constructors");
1155 
1156  std::string mname = args(0).string_value ();
1157  std::string cname = args(1).string_value ();
1158 
1159  cdef_class cls = lookup_class (cname);
1160 
1161  if (in_constructor)
1162  {
1163  if (! is_direct_superclass (cls, ctx))
1164  error ("`%s' is not a direct superclass of `%s'",
1165  cname.c_str (), ctx.get_name ().c_str ());
1166 
1167  if (! is_constructed_object (mname))
1168  error ("cannot call superclass constructor with variable `%s'",
1169  mname.c_str ());
1170 
1171  octave_value sym = symbol_table::varval (mname);
1172 
1173  cls.run_constructor (to_cdef_ref (sym), idx);
1174 
1175  retval(0) = sym;
1176  }
1177  else
1178  {
1179  if (mname != meth_name)
1180  error ("method name mismatch (`%s' != `%s')",
1181  mname.c_str (), meth_name.c_str ());
1182 
1183  if (! is_strict_superclass (cls, ctx))
1184  error ("`%s' is not a superclass of `%s'",
1185  cname.c_str (), ctx.get_name ().c_str ());
1186 
1187  // I see 2 possible implementations here:
1188  // 1) use cdef_object::subsref with a different class
1189  // context; this avoids duplicating code, but
1190  // assumes the object is always the first argument
1191  // 2) lookup the method manually and call
1192  // cdef_method::execute; this duplicates part of
1193  // logic in cdef_object::subsref, but avoid the
1194  // assumption of 1)
1195  // Not being sure about the assumption of 1), I
1196  // go with option 2) for the time being.
1197 
1198  cdef_method meth = cls.find_method (meth_name, false);
1199 
1200  if (! meth.ok ())
1201  error ("no method `%s' found in superclass `%s'",
1202  meth_name.c_str (), cname.c_str ());
1203 
1204  retval = meth.execute (idx, nargout, true,
1205  meth_name);
1206  }
1207 
1208  return retval;
1209  }
1210 
1211 private:
1213  {
1215 
1216  if (of->is_classdef_constructor ())
1217  {
1218  octave_user_function *uf = of->user_function_value (true);
1219 
1220  if (uf)
1221  {
1222  tree_parameter_list *ret_list = uf->return_list ();
1223 
1224  if (ret_list && ret_list->length () == 1)
1225  return (ret_list->front ()->name () == nm);
1226  }
1227  }
1228 
1229  return false;
1230  }
1231 
1232 private:
1234 };
1235 
1236 //----------------------------------------------------------------------------
1237 
1238 octave_map
1240 {
1242 
1243  warning_with_id ("Octave:classdef-to-struct",
1244  "struct: converting a classdef object into a struct "
1245  "overrides the access restrictions defined for properties. "
1246  "All properties are returned, including private and "
1247  "protected ones.");
1248 
1249  cdef_class cls = get_class ();
1250 
1251  if (cls.ok ())
1252  {
1253  std::map<std::string, cdef_property> props;
1254 
1256 
1257  for (std::map<std::string, cdef_property>::iterator it = props.begin ();
1258  it != props.end (); ++it)
1259  {
1260  if (is_array ())
1261  {
1262  Array<cdef_object> a_obj = array_value ();
1263 
1264  Cell cvalue (a_obj.dims ());
1265 
1266  for (octave_idx_type i = 0; i < a_obj.numel (); i++)
1267  cvalue (i) = it->second.get_value (a_obj(i), false);
1268 
1269  retval.setfield (it->first, cvalue);
1270  }
1271  else
1272  {
1273  Cell cvalue (dim_vector (1, 1),
1274  it->second.get_value (*this, false));
1275 
1276  retval.setfield (it->first, cvalue);
1277  }
1278  }
1279  }
1280 
1281  return retval;
1282 }
1283 
1286 {
1287  cdef_class cls = get_class ();
1288 
1289  if (cls.ok ())
1290  return cls.get_names ();
1291 
1292  return string_vector ();
1293 }
1294 
1297  const std::list<octave_value_list>& idx,
1298  int nargout, size_t& skip,
1299  const cdef_class& context, bool auto_add)
1300 {
1301  skip = 0;
1302 
1303  cdef_class cls = (context.ok () ? context : get_class ());
1304 
1306 
1307  if (! cls.ok ())
1308  return retval;
1309 
1310  switch (type[0])
1311  {
1312  case '.':
1313  {
1314  std::string name = (idx.front ())(0).string_value ();
1315 
1316  cdef_method meth = cls.find_method (name);
1317 
1318  if (meth.ok ())
1319  {
1320  int _nargout = (type.length () > 2 ? 1 : nargout);
1321 
1323 
1324  skip = 1;
1325 
1326  if (type.length () > 1 && type[1] == '(')
1327  {
1328  std::list<octave_value_list>::const_iterator it = idx.begin ();
1329 
1330  args = *++it;
1331 
1332  skip++;
1333  }
1334 
1335  if (meth.is_static ())
1336  retval = meth.execute (args, _nargout, true, "subsref");
1337  else
1338  {
1339  refcount++;
1340  retval = meth.execute (cdef_object (this), args, _nargout,
1341  true, "subsref");
1342  }
1343  }
1344 
1345  if (skip == 0)
1346  {
1347  cdef_property prop = cls.find_property (name);
1348 
1349  if (! prop.ok ())
1350  error ("subsref: unknown method or property: %s", name.c_str ());
1351 
1352  if (prop.is_constant ())
1353  retval(0) = prop.get_value (true, "subsref");
1354  else
1355  {
1356  refcount++;
1357  retval(0) = prop.get_value (cdef_object (this),
1358  true, "subsref");
1359  }
1360 
1361  skip = 1;
1362  }
1363  break;
1364  }
1365 
1366  case '(':
1367  {
1368  const octave_value_list& ival = idx.front ();
1369 
1370  refcount++;
1371  cdef_object this_obj (this);
1372 
1373  if (ival.empty ())
1374  {
1375  skip++;
1376  retval(0) = to_ov (this_obj);
1377  }
1378  else
1379  {
1380  Array<cdef_object> arr (dim_vector (1, 1), this_obj);
1381 
1382  cdef_object new_obj = cdef_object (new cdef_object_array (arr));
1383 
1384  new_obj.set_class (get_class ());
1385 
1386  retval = new_obj.subsref (type, idx, nargout, skip, cls, auto_add);
1387  }
1388  }
1389  break;
1390 
1391  default:
1392  error ("object cannot be indexed with `%c'", type[0]);
1393  break;
1394  }
1395 
1396  return retval;
1397 }
1398 
1401  const std::list<octave_value_list>& idx,
1402  const octave_value& rhs)
1403 {
1405 
1406  cdef_class cls = get_class ();
1407 
1408  switch (type[0])
1409  {
1410  case '.':
1411  {
1412  std::string name = (idx.front ())(0).string_value ();
1413 
1414  cdef_property prop = cls.find_property (name);
1415 
1416  if (! prop.ok ())
1417  error ("subsasgn: unknown property: %s", name.c_str ());
1418 
1419  if (prop.is_constant ())
1420  error ("subsasgn: cannot assign constant property: %s",
1421  name.c_str ());
1422 
1423  refcount++;
1424 
1425  cdef_object obj (this);
1426 
1427  if (type.length () == 1)
1428  {
1429  prop.set_value (obj, rhs, true, "subsasgn");
1430 
1431  retval = to_ov (obj);
1432  }
1433  else
1434  {
1435  octave_value val =
1436  prop.get_value (obj, true, "subsasgn");
1437 
1438  std::list<octave_value_list> args (idx);
1439 
1440  args.erase (args.begin ());
1441 
1442  val = val.assign (octave_value::op_asn_eq,
1443  type.substr (1), args, rhs);
1444 
1445  if (val.class_name () != "object"
1446  || ! to_cdef (val).is_handle_object ())
1447  prop.set_value (obj, val, true, "subsasgn");
1448 
1449  retval = to_ov (obj);
1450  }
1451  }
1452  break;
1453 
1454  case '(':
1455  {
1456  refcount++;
1457 
1458  cdef_object this_obj (this);
1459 
1460  Array<cdef_object> arr (dim_vector (1, 1), this_obj);
1461 
1462  cdef_object new_obj = cdef_object (new cdef_object_array (arr));
1463 
1464  new_obj.set_class (get_class ());
1465 
1466  octave_value tmp = new_obj.subsasgn (type, idx, rhs);
1467 
1468  retval = tmp;
1469  }
1470  break;
1471 
1472  default:
1473  error ("subsasgn: object cannot be index with `%c'", type[0]);
1474  break;
1475  }
1476 
1477  return retval;
1478 }
1479 
1480 void
1482 {
1483  std::string cls_name = cls.get_name ();
1484 
1485  Cell supcls = cls.get ("SuperClasses").cell_value ();
1486 
1487  std::list<cdef_class> supcls_list = lookup_classes (supcls);
1488 
1489  ctor_list[cls] = supcls_list;
1490 }
1491 
1494  const std::list<octave_value_list>& idx,
1495  int /* nargout */, size_t& skip,
1496  const cdef_class& /* context */, bool auto_add)
1497 {
1499 
1500  skip = 1;
1501 
1502  switch (type[0])
1503  {
1504  case '(':
1505  {
1506  const octave_value_list& ival = idx.front ();
1507 
1508  if (ival.empty ())
1509  {
1510  refcount++;
1511  retval(0) = to_ov (cdef_object (this));
1512  break;
1513  }
1514 
1515  bool is_scalar = true;
1516  Array<idx_vector> iv (dim_vector (1, ival.length ()));
1517 
1518  for (int i = 0; i < ival.length (); i++)
1519  {
1520  try
1521  {
1522  iv(i) = ival(i).index_vector ();
1523  }
1524  catch (octave::index_exception& e)
1525  {
1526  // Rethrow to allow more info to be reported later.
1527  e.set_pos_if_unset (ival.length (), i+1);
1528  throw;
1529  }
1530 
1531  is_scalar = is_scalar && iv(i).is_scalar ();
1532  }
1533 
1534  Array<cdef_object> ires = array.index (iv, auto_add);
1535 
1536  // If resizing is enabled (auto_add = true), it's possible
1537  // indexing was out-of-bound and the result array contains
1538  // invalid cdef_objects.
1539 
1540  if (auto_add)
1541  fill_empty_values (ires);
1542 
1543  if (is_scalar)
1544  retval(0) = to_ov (ires(0));
1545  else
1546  {
1547  cdef_object array_obj (new cdef_object_array (ires));
1548 
1549  array_obj.set_class (get_class ());
1550 
1551  retval(0) = to_ov (array_obj);
1552  }
1553  }
1554  break;
1555 
1556  case '.':
1557  if (type.size () == 1 && idx.size () == 1)
1558  {
1559  Cell c (dims ());
1560 
1561  octave_idx_type n = array.numel ();
1562 
1563  // dummy variables
1564  size_t dummy_skip;
1565  cdef_class dummy_cls;
1566 
1567  for (octave_idx_type i = 0; i < n; i++)
1568  {
1569  octave_value_list r = array(i).subsref (type, idx, 1, dummy_skip,
1570  dummy_cls);
1571 
1572  if (r.length () > 0)
1573  c(i) = r(0);
1574  }
1575 
1576  retval(0) = octave_value (c, true);
1577 
1578  break;
1579  }
1580  // fall through "default"
1581 
1582  default:
1583  error ("can't perform indexing operation on array of %s objects",
1584  class_name ().c_str ());
1585  break;
1586  }
1587 
1588  return retval;
1589 }
1590 
1593  const std::list<octave_value_list>& idx,
1594  const octave_value& rhs)
1595 {
1597 
1598  switch (type[0])
1599  {
1600  case '(':
1601  if (type.length () == 1)
1602  {
1603  cdef_object rhs_obj = to_cdef (rhs);
1604 
1605  if (rhs_obj.get_class () != get_class ())
1606  error ("can't assign %s object into array of %s objects.",
1607  rhs_obj.class_name ().c_str (),
1608  class_name ().c_str ());
1609 
1610  const octave_value_list& ival = idx.front ();
1611  bool is_scalar = true;
1612  Array<idx_vector> iv (dim_vector (1, ival.length ()));
1613 
1614  for (int i = 0; i < ival.length (); i++)
1615  {
1616  try
1617  {
1618  iv(i) = ival(i).index_vector ();
1619  }
1620  catch (octave::index_exception& e)
1621  {
1622  e.set_pos_if_unset (ival.length (), i+1);
1623  throw; // var name set in pt-idx.cc / pt-assign.cc
1624  }
1625 
1626  is_scalar = is_scalar && iv(i).is_scalar ();
1627  }
1628 
1629  Array<cdef_object> rhs_mat;
1630 
1631  if (! rhs_obj.is_array ())
1632  {
1633  rhs_mat = Array<cdef_object> (dim_vector (1, 1));
1634  rhs_mat(0) = rhs_obj;
1635  }
1636  else
1637  rhs_mat = rhs_obj.array_value ();
1638 
1639  octave_idx_type n = array.numel ();
1640 
1641  array.assign (iv, rhs_mat, cdef_object ());
1642 
1643  if (array.numel () > n)
1644  fill_empty_values ();
1645 
1646  refcount++;
1647  retval = to_ov (cdef_object (this));
1648  }
1649  else
1650  {
1651  const octave_value_list& ival = idx.front ();
1652 
1653  bool is_scalar = true;
1654 
1655  Array<idx_vector> iv (dim_vector (1, std::max (ival.length (),
1656  static_cast<octave_idx_type> (2))));
1657 
1658  for (int i = 0; i < ival.length (); i++)
1659  {
1660  try
1661  {
1662  iv(i) = ival(i).index_vector ();
1663  }
1664  catch (octave::index_exception& e)
1665  {
1666  // Rethrow to allow more info to be reported later.
1667  e.set_pos_if_unset (ival.length (), i+1);
1668  throw;
1669  }
1670 
1671  is_scalar = is_scalar && iv(i).is_scalar ();
1672 
1673  if (! is_scalar)
1674  error ("subsasgn: invalid indexing for object array assignment"
1675  ", the index must reference a single object in the "
1676  "array.");
1677  }
1678 
1679  // Fill in trailing singleton dimensions so that
1680  // array.index doesn't create a new blank entry (bug #46660).
1681  for (int i = ival.length (); i < 2; i++)
1682  iv(i) = static_cast<octave_idx_type> (1);
1683 
1684  Array<cdef_object> a = array.index (iv, true);
1685 
1686  if (a.numel () != 1)
1687  error ("subsasgn: invalid indexing for object array assignment");
1688 
1689  cdef_object obj = a(0);
1690 
1691  int ignore_copies = 0;
1692 
1693  // If the object in 'a' is not valid, this means the index
1694  // was out-of-bound and we need to create a new object.
1695 
1696  if (! obj.ok ())
1698  else
1699  // Optimize the subsasgn call to come. There are 2 copies
1700  // that we can safely ignore:
1701  // - 1 in "array"
1702  // - 1 in "a"
1703  ignore_copies = 2;
1704 
1705  std::list<octave_value_list> next_idx (idx);
1706 
1707  next_idx.erase (next_idx.begin ());
1708 
1709  octave_value tmp = obj.subsasgn (type.substr (1), next_idx,
1710  rhs, ignore_copies);
1711 
1712  cdef_object robj = to_cdef (tmp);
1713 
1714  if (! robj.ok ()
1715  || robj.is_array ()
1716  || robj.get_class () != get_class ())
1717  error ("subasgn: invalid assignment into array of %s objects",
1718  class_name ().c_str ());
1719 
1720  // Small optimization, when dealing with handle
1721  // objects, we don't need to re-assign the result
1722  // of subsasgn back into the array.
1723 
1724  if (! robj.is (a(0)))
1725  {
1726  Array<cdef_object> rhs_a (dim_vector (1, 1),
1727  robj);
1728 
1729  octave_idx_type n = array.numel ();
1730 
1731  array.assign (iv, rhs_a);
1732 
1733  if (array.numel () > n)
1734  fill_empty_values ();
1735  }
1736 
1737  refcount++;
1738 
1739  retval = to_ov (cdef_object (this));
1740  }
1741  break;
1742 
1743  default:
1744  error ("can't perform indexing operation on array of %s objects",
1745  class_name ().c_str ());
1746  break;
1747  }
1748 
1749  return retval;
1750 }
1751 
1752 void
1754 {
1755  cdef_class cls = get_class ();
1756 
1757  cdef_object obj;
1758 
1759  int n = arr.numel ();
1760 
1761  for (int i = 0; i < n; i++)
1762  {
1763  if (! arr.xelem (i).ok ())
1764  {
1765  if (! obj.ok ())
1766  {
1767  obj = cls.construct_object (octave_value_list ());
1768 
1769  arr.xelem (i) = obj;
1770  }
1771  else
1772  arr.xelem (i) = obj.copy ();
1773  }
1774  }
1775 }
1776 
1777 bool
1779 {
1780  return (is_constructed ()
1781  || ctor_list.find (cls) == ctor_list.end ());
1782 }
1783 
1784 bool
1786 {
1787  std::map< cdef_class, std::list<cdef_class> >::const_iterator it;
1788 
1789  if (is_constructed ())
1790  return true;
1791  else if ((it = ctor_list.find (cls)) == ctor_list.end ()
1792  || it->second.empty ())
1793  return true;
1794 
1795  for (std::list<cdef_class>::const_iterator lit = it->second.begin ();
1796  lit != it->second.end (); ++lit)
1797  if (! is_constructed_for (*lit))
1798  return false;
1799 
1800  return true;
1801 }
1802 
1803 inline void
1805 {
1806  ctor_list.erase (cls);
1807 }
1808 
1810 {
1811 #if DEBUG_TRACE
1812  std::cerr << "deleting " << get_class ().get_name ()
1813  << " object (handle)" << std::endl;
1814 #endif
1815 }
1816 
1818 {
1819 #if DEBUG_TRACE
1820  std::cerr << "deleting " << get_class ().get_name ()
1821  << " object (value)" << std::endl;
1822 #endif
1823 }
1824 
1825 cdef_class::cdef_class_rep::cdef_class_rep (const std::list<cdef_class>&
1826  superclasses)
1827  : cdef_meta_object_rep (), member_count (0), handle_class (false),
1828  object_count (0), meta (false)
1829 {
1830  put ("SuperClasses", to_ov (superclasses));
1831  implicit_ctor_list = superclasses;
1832 }
1833 
1836 {
1837  method_iterator it = method_map.find (nm);
1838 
1839  if (it == method_map.end ())
1840  {
1841  // FIXME: look into class directory
1842  }
1843  else
1844  {
1845  cdef_method& meth = it->second;
1846 
1847  // FIXME: check if method reload needed
1848 
1849  if (meth.ok ())
1850  return meth;
1851  }
1852 
1853  if (! local)
1854  {
1855  // Look into superclasses
1856 
1857  Cell super_classes = get ("SuperClasses").cell_value ();
1858 
1859  for (int i = 0; i < super_classes.numel (); i++)
1860  {
1861  cdef_class cls = lookup_class (super_classes(i));
1862 
1863  cdef_method meth = cls.find_method (nm);
1864 
1865  if (meth.ok ())
1866  return meth;
1867  }
1868  }
1869 
1870  return cdef_method ();
1871 }
1872 
1874 {
1875 public:
1876  ctor_analyzer (const std::string& ctor, const std::string& obj)
1877  : tree_walker (), who (ctor), obj_name (obj) { }
1878 
1880  {
1882  it != t.end (); ++it)
1883  (*it)->accept (*this);
1884  }
1885 
1887  {
1888  if (t.is_expression ())
1889  t.expression ()->accept (*this);
1890  }
1891 
1893  {
1894  t.right_hand_side ()->accept (*this);
1895  }
1896 
1898  {
1899  t.right_hand_side ()->accept (*this);
1900  }
1901 
1903  {
1904  t.expression ()->accept (*this);
1905  }
1906 
1908  {
1909  octave_value fcn = t.function ();
1910 
1911  if (fcn.is_function ())
1912  {
1913  octave_function *of = fcn.function_value (true);
1914 
1915  if (of)
1916  {
1917  if (of->name () == "__superclass_reference__")
1918  {
1920 
1921  if (args(0).string_value () == obj_name)
1922  {
1923  std::string class_name = args(1).string_value ();
1924 
1925  cdef_class cls = lookup_class (class_name, false);
1926 
1927  if (cls.ok ())
1928  ctor_list.push_back (cls);
1929  }
1930  }
1931  }
1932  }
1933  }
1934 
1935  std::list<cdef_class> get_constructor_list (void) const
1936  { return ctor_list; }
1937 
1938  // NO-OP
1962  void visit_cell (tree_cell&) { }
1975 
1976 private:
1977  // The name of the constructor being analyzed.
1979 
1980  // The name of the first output argument of the constructor.
1982 
1983  // The list of superclass constructors that are explicitly called.
1984  std::list<cdef_class> ctor_list;
1985 };
1986 
1987 void
1989 {
1990  method_map[meth.get_name ()] = meth;
1991 
1992  member_count++;
1993 
1994  if (meth.is_constructor ())
1995  {
1996  // Analyze the constructor code to determine what superclass
1997  // constructors are called explicitly.
1998 
1999  octave_function *of = meth.get_function ().function_value (true);
2000 
2001  if (of)
2002  {
2003  octave_user_function *uf = of->user_function_value (true);
2004 
2005  if (uf)
2006  {
2007  tree_parameter_list *ret_list = uf->return_list ();
2008  tree_statement_list *body = uf->body ();
2009 
2010  if (! ret_list || ret_list->size () != 1)
2011  error ("%s: invalid constructor output arguments",
2012  meth.get_name ().c_str ());
2013 
2014  std::string obj_name = ret_list->front ()->name ();
2015  ctor_analyzer a (meth.get_name (), obj_name);
2016 
2017  body->accept (a);
2018 
2019  std::list<cdef_class> explicit_ctor_list
2020  = a.get_constructor_list ();
2021 
2022  for (std::list<cdef_class>::const_iterator
2023  it = explicit_ctor_list.begin ();
2024  it != explicit_ctor_list.end ();
2025  ++it)
2026  {
2027 #if DEBUG_TRACE
2028  std::cerr << "explicit superclass constructor: "
2029  << it->get_name () << std::endl;
2030 #endif
2031 
2032  implicit_ctor_list.remove (*it);
2033  }
2034  }
2035  }
2036  }
2037 }
2038 
2039 void
2041 {
2042  // FIXME: re-scan class directory
2043 }
2044 
2045 Cell
2047 {
2048  std::map<std::string,cdef_method> meths;
2049 
2050  find_methods (meths, false);
2051 
2052  Cell c (meths.size (), 1);
2053 
2054  int idx = 0;
2055 
2056  for (std::map<std::string,cdef_method>::const_iterator
2057  it = meths.begin (); it != meths.end (); ++it, ++idx)
2058  c (idx, 0) = to_ov (it->second);
2059 
2060  return c;
2061 }
2062 
2063 void
2065  cdef_method>& meths,
2066  bool only_inherited)
2067 {
2068  load_all_methods ();
2069 
2071 
2072  for (it = method_map.begin (); it != method_map.end (); ++it)
2073  {
2074  if (! it->second.is_constructor ())
2075  {
2076  std::string nm = it->second.get_name ();
2077 
2078  if (meths.find (nm) == meths.end ())
2079  {
2080  if (only_inherited)
2081  {
2082  octave_value acc = it->second.get ("Access");
2083 
2084  if (! acc.is_string ()
2085  || acc.string_value () == "private")
2086  continue;
2087  }
2088 
2089  meths[nm] = it->second;
2090  }
2091  }
2092  }
2093 
2094  // Look into superclasses
2095 
2096  Cell super_classes = get ("SuperClasses").cell_value ();
2097 
2098  for (int i = 0; i < super_classes.numel (); i++)
2099  {
2100  cdef_class cls = lookup_class (super_classes(i));
2101 
2102  cls.get_rep ()->find_methods (meths, true);
2103  }
2104 }
2105 
2108 {
2109  property_iterator it = property_map.find (nm);
2110 
2111  if (it != property_map.end ())
2112  {
2113  cdef_property& prop = it->second;
2114 
2115  if (prop.ok ())
2116  return prop;
2117  }
2118 
2119  // Look into superclasses
2120 
2121  Cell super_classes = get ("SuperClasses").cell_value ();
2122 
2123  for (int i = 0; i < super_classes.numel (); i++)
2124  {
2125  cdef_class cls = lookup_class (super_classes(i));
2126 
2127  cdef_property prop = cls.find_property (nm);
2128 
2129  if (prop.ok ())
2130  return prop;
2131  }
2132 
2133  return cdef_property ();
2134 }
2135 
2136 void
2138 {
2139  property_map[prop.get_name ()] = prop;
2140 
2141  member_count++;
2142 }
2143 
2144 Cell
2146 {
2147  std::map<std::string,cdef_property> props;
2148 
2149  props = get_property_map (mode);
2150 
2151  Cell c (props.size (), 1);
2152 
2153  int idx = 0;
2154 
2155  for (std::map<std::string,cdef_property>::const_iterator
2156  it = props.begin (); it != props.end (); ++it, ++idx)
2157  c (idx, 0) = to_ov (it->second);
2158 
2159  return c;
2160 }
2161 
2162 std::map<std::string, cdef_property>
2164 {
2165  std::map<std::string,cdef_property> props;
2166 
2167  find_properties (props, mode);
2168 
2169  return props;
2170 }
2171 
2172 void
2174  cdef_property>& props,
2175  int mode)
2176 {
2178 
2179  for (it = property_map.begin (); it != property_map.end (); ++it)
2180  {
2181  std::string nm = it->second.get_name ();
2182 
2183  if (props.find (nm) == props.end ())
2184  {
2185  if (mode == property_inherited)
2186  {
2187  octave_value acc = it->second.get ("GetAccess");
2188 
2189  if (! acc.is_string ()
2190  || acc.string_value () == "private")
2191  continue;
2192  }
2193 
2194  props[nm] = it->second;
2195  }
2196  }
2197 
2198  // Look into superclasses
2199 
2200  Cell super_classes = get ("SuperClasses").cell_value ();
2201 
2202  for (int i = 0; i < super_classes.numel (); i++)
2203  {
2204  cdef_class cls = lookup_class (super_classes(i));
2205 
2206  cls.get_rep ()->find_properties (props,
2207  (mode == property_all
2208  ? property_all
2209  : property_inherited));
2210  }
2211 }
2212 
2213 void
2214 cdef_class::cdef_class_rep::find_names (std::set<std::string>& names,
2215  bool all)
2216 {
2217  load_all_methods ();
2218 
2219  for (method_const_iterator it = method_map.begin ();
2220  it != method_map.end(); ++it)
2221  {
2222  if (! it->second.is_constructor ())
2223  {
2224  std::string nm = it->second.get_name ();
2225 
2226  if (! all)
2227  {
2228  octave_value acc = it->second.get ("Access");
2229 
2230  if (! acc.is_string()
2231  || acc.string_value () != "public")
2232  continue;
2233  }
2234 
2235  names.insert (nm);
2236  }
2237  }
2238 
2239  for (property_const_iterator it = property_map.begin ();
2240  it != property_map.end (); ++it)
2241  {
2242  std::string nm = it->second.get_name ();
2243 
2244  if (! all)
2245  {
2246  octave_value acc = it->second.get ("GetAccess");
2247 
2248  if (! acc.is_string()
2249  || acc.string_value () != "public")
2250  continue;
2251  }
2252 
2253  names.insert (nm);
2254  }
2255 
2256  // Look into superclasses
2257 
2258  Cell super_classes = get ("SuperClasses").cell_value ();
2259 
2260  for (int i = 0; i < super_classes.numel (); i++)
2261  {
2262  cdef_class cls = lookup_class (super_classes(i));
2263 
2264  cls.get_rep ()->find_names (names, all);
2265  }
2266 }
2267 
2270 {
2271  std::set<std::string> names;
2272 
2273  find_names (names, false);
2274 
2275  string_vector v (names);
2276 
2277  return v.sort (true);
2278 }
2279 
2280 void
2282 {
2283  method_iterator it = method_map.find ("delete");
2284 
2285  if (it != method_map.end ())
2286  {
2287  cdef_class cls = obj.get_class ();
2288 
2289  obj.set_class (wrap ());
2290 
2291  it->second.execute (obj, octave_value_list (), 0, false);
2292 
2293  obj.set_class (cls);
2294  }
2295 
2296  // FIXME: should we destroy corresponding properties here?
2297 
2298  // Call "delete" in super classes
2299 
2300  Cell super_classes = get ("SuperClasses").cell_value ();
2301 
2302  for (int i = 0; i < super_classes.numel (); i++)
2303  {
2304  cdef_class cls = lookup_class (super_classes(i));
2305 
2306  cls.delete_object (obj);
2307  }
2308 }
2309 
2312  const std::list<octave_value_list>& idx,
2313  int nargout)
2314 {
2315  size_t skip = 1;
2316 
2318 
2319  switch (type[0])
2320  {
2321  case '(':
2322  // Constructor call
2323 
2324 #if DEBUG_TRACE
2325  std::cerr << "constructor" << std::endl;
2326 #endif
2327 
2328  retval(0) = construct (idx.front ());
2329  break;
2330 
2331  case '.':
2332  {
2333  // Static method, constant (or property?)
2334 
2335 #if DEBUG_TRACE
2336  std::cerr << "static method/property" << std::endl;
2337 #endif
2338 
2339  if (idx.front ().length () != 1)
2340  error ("invalid meta.class indexing");
2341 
2342  std::string nm = idx.front ()(0).xstring_value ("invalid meta.class indexing, expected a method or property name");
2343 
2344  cdef_method meth = find_method (nm);
2345 
2346  if (meth.ok ())
2347  {
2348  if (! meth.is_static ())
2349  error ("method `%s' is not static", nm.c_str ());
2350 
2352 
2353  if (type.length () > 1 && idx.size () > 1
2354  && type[1] == '(')
2355  {
2356  args = *(++(idx.begin ()));
2357  skip++;
2358  }
2359 
2360  retval = meth.execute (args, (type.length () > skip
2361  ? 1 : nargout), true,
2362  "meta.class");
2363  }
2364  else
2365  {
2366  cdef_property prop = find_property (nm);
2367 
2368  if (! prop.ok ())
2369  error ("no such method or property `%s'", nm.c_str ());
2370 
2371  if (! prop.is_constant ())
2372  error ("property `%s' is not constant", nm.c_str ());
2373 
2374  retval(0) = prop.get_value (true, "meta.class");
2375  }
2376  }
2377  break;
2378 
2379  default:
2380  error ("invalid meta.class indexing");
2381  break;
2382  }
2383 
2384  if (type.length () > skip && idx.size () > skip && ! retval.empty ())
2385  retval = retval(0).next_subsref (nargout, type, idx, skip);
2386 
2387  return retval;
2388 }
2389 
2390 void
2392 {
2394 }
2395 
2396 void
2398 {
2399  // Populate the object with default property values
2400 
2401  std::list<cdef_class> super_classes = lookup_classes (
2402  get ("SuperClasses").cell_value ());
2403 
2404  for (std::list<cdef_class>::iterator it = super_classes.begin ();
2405  it != super_classes.end (); ++it)
2406  it->initialize_object (obj);
2407 
2408  for (property_const_iterator it = property_map.begin ();
2409  it != property_map.end (); ++it)
2410  {
2411  if (! it->second.get ("Dependent").bool_value ())
2412  {
2413  octave_value pvalue = it->second.get ("DefaultValue");
2414 
2415  if (pvalue.is_defined ())
2416  obj.put (it->first, pvalue);
2417  else
2418  obj.put (it->first, octave_value (Matrix ()));
2419  }
2420  }
2421 
2422  refcount++;
2423  obj.mark_for_construction (cdef_class (this));
2424 }
2425 
2426 void
2428  const octave_value_list& args)
2429 {
2430  octave_value_list empty_args;
2431 
2432  for (std::list<cdef_class>::const_iterator it = implicit_ctor_list.begin ();
2433  it != implicit_ctor_list.end (); ++it)
2434  {
2435  cdef_class supcls = lookup_class (*it);
2436 
2437  supcls.run_constructor (obj, empty_args);
2438  }
2439 
2440  std::string cls_name = get_name ();
2441  std::string ctor_name = get_base_name (cls_name);
2442 
2443  cdef_method ctor = find_method (ctor_name);
2444 
2445  if (ctor.ok ())
2446  {
2447  octave_value_list ctor_args (args);
2448  octave_value_list ctor_retval;
2449 
2450  ctor_args.prepend (to_ov (obj));
2451  ctor_retval = ctor.execute (ctor_args, 1, true, "constructor");
2452 
2453  if (ctor_retval.length () != 1)
2454  error ("%s: invalid number of output arguments for classdef constructor",
2455  ctor_name.c_str ());
2456 
2457  obj = to_cdef (ctor_retval(0));
2458  }
2459 
2460  obj.mark_as_constructed (wrap ());
2461 }
2462 
2465 {
2466  cdef_object obj = construct_object (args);
2467 
2468  if (obj.ok ())
2469  return to_ov (obj);
2470 
2471  return octave_value ();
2472 }
2473 
2476 {
2477  if (is_abstract ())
2478  error ("cannot instantiate object for abstract class `%s'",
2479  get_name ().c_str ());
2480 
2481  cdef_object obj;
2482 
2483  if (is_meta_class ())
2484  {
2485  // This code path is only used to create empty meta objects
2486  // as filler for the empty values within a meta object array.
2487 
2488  cdef_class this_cls = wrap ();
2489 
2490  static cdef_object empty_class;
2491 
2492  if (this_cls == cdef_class::meta_class ())
2493  {
2494  if (! empty_class.ok ())
2495  empty_class = make_class ("", std::list<cdef_class> ());
2496  obj = empty_class;
2497  }
2498  else if (this_cls == cdef_class::meta_property ())
2499  {
2500  static cdef_property empty_property;
2501 
2502  if (! empty_class.ok ())
2503  empty_class = make_class ("", std::list<cdef_class> ());
2504  if (! empty_property.ok ())
2505  empty_property = make_property (empty_class, "");
2506  obj = empty_property;
2507  }
2508  else if (this_cls == cdef_class::meta_method ())
2509  {
2510  static cdef_method empty_method;
2511 
2512  if (! empty_class.ok ())
2513  empty_class = make_class ("", std::list<cdef_class> ());
2514  if (! empty_method.ok ())
2515  empty_method = make_method (empty_class, "", octave_value ());
2516  obj = empty_method;
2517  }
2518  else if (this_cls == cdef_class::meta_package ())
2519  {
2520  static cdef_package empty_package;
2521 
2522  if (! empty_package.ok ())
2523  empty_package = make_package ("");
2524  obj = empty_package;
2525  }
2526  else
2527  panic_impossible ();
2528 
2529  return obj;
2530  }
2531  else
2532  {
2533  if (is_handle_class ())
2534  obj = cdef_object (new handle_cdef_object ());
2535  else
2536  obj = cdef_object (new value_cdef_object ());
2537  obj.set_class (wrap ());
2538 
2539  initialize_object (obj);
2540 
2541  run_constructor (obj, args);
2542 
2543  return obj;
2544  }
2545 
2546  return cdef_object ();
2547 }
2548 
2549 static octave_value
2551 {
2552  if (t->expression ())
2553  {
2554  if (t->expression ()->is_identifier ())
2555  {
2556  std::string s = t->expression ()->name ();
2557 
2558  if (s == "public")
2559  return std::string ("public");
2560  else if (s == "protected")
2561  return std::string ("protected");
2562  else if (s == "private")
2563  return std::string ("private");
2564  }
2565 
2566  return t->expression ()->rvalue1 ();
2567  }
2568  else
2569  return octave_value (true);
2570 }
2571 
2572 template <typename T>
2573 static std::string
2575 {
2576  if (v.is_string ())
2577  return v.string_value ();
2578  else if (t->expression ())
2579  return t->expression ()->original_text ();
2580  else
2581  return std::string ("true");
2582 }
2583 
2584 cdef_class
2586 {
2588  std::string class_name, full_class_name;
2589 
2590  // Class creation
2591 
2592  class_name = full_class_name = t->ident ()->name ();
2593  if (! t->package_name ().empty ())
2594  full_class_name = t->package_name () + "." + full_class_name;
2595 
2596 #if DEBUG_TRACE
2597  std::cerr << "class: " << full_class_name << std::endl;
2598 #endif
2599 
2600  std::list<cdef_class> slist;
2601 
2602  if (t->superclass_list ())
2603  {
2605  t->superclass_list ()->begin ();
2606  it != t->superclass_list ()->end (); ++it)
2607  {
2608  std::string sclass_name = (*it)->class_name ();
2609 
2610 #if DEBUG_TRACE
2611  std::cerr << "superclass: " << sclass_name << std::endl;
2612 #endif
2613 
2614  cdef_class sclass = lookup_class (sclass_name);
2615 
2616  if (sclass.get ("Sealed").bool_value ())
2617  error ("`%s' cannot inherit from `%s', because it is sealed",
2618  full_class_name.c_str (), sclass_name.c_str ());
2619 
2620  slist.push_back (sclass);
2621  }
2622  }
2623 
2624  retval = ::make_class (full_class_name, slist);
2625 
2626  // Package owning this class
2627 
2628  if (! t->package_name ().empty ())
2629  {
2631 
2632  if (pack.ok ())
2633  retval.put ("ContainingPackage", to_ov (pack));
2634  }
2635 
2636  // Class attributes
2637 
2638  if (t->attribute_list ())
2639  {
2641  it = t->attribute_list ()->begin ();
2642  it != t->attribute_list ()->end ();
2643  ++it)
2644  {
2645  std::string aname = (*it)->ident ()->name ();
2646  octave_value avalue = compute_attribute_value (*it);
2647 
2648 #if DEBUG_TRACE
2649  std::cerr << "class attribute: " << aname << " = "
2650  << attribute_value_to_string (*it, avalue) << std::endl;
2651 #endif
2652 
2653  retval.put (aname, avalue);
2654  }
2655  }
2656 
2657  tree_classdef_body* b = t->body ();
2658 
2659  if (b)
2660  {
2661  // Keep track of the get/set accessor methods. They will be used
2662  // later on when creating properties.
2663 
2664  std::map<std::string, octave_value> get_methods;
2665  std::map<std::string, octave_value> set_methods;
2666 
2667  // Method blocks
2668 
2669  std::list<tree_classdef_methods_block *> mb_list = b->methods_list ();
2670 
2671  for (tree_classdef_body::methods_list_iterator it = mb_list.begin ();
2672  it != mb_list.end (); ++it)
2673  {
2674  std::map<std::string, octave_value> amap;
2675 
2676 #if DEBUG_TRACE
2677  std::cerr << "method block" << std::endl;
2678 #endif
2679 
2680  // Method attributes
2681 
2682  if ((*it)->attribute_list ())
2683  {
2685  (*it)->attribute_list ()->begin ();
2686  ait != (*it)->attribute_list ()->end (); ++ait)
2687  {
2688  std::string aname = (*ait)->ident ()->name ();
2689  octave_value avalue = compute_attribute_value (*ait);
2690 
2691 #if DEBUG_TRACE
2692  std::cerr << "method attribute: " << aname << " = "
2693  << attribute_value_to_string (*ait, avalue)
2694  << std::endl;
2695 #endif
2696 
2697  amap[aname] = avalue;
2698  }
2699  }
2700 
2701  // Methods
2702 
2703  if ((*it)->element_list ())
2704  {
2706  (*it)->element_list ()->begin ();
2707  mit != (*it)->element_list ()->end (); ++mit)
2708  {
2709  std::string mname = mit->function_value ()->name ();
2710  std::string mprefix = mname.substr (0, 4);
2711 
2712  if (mprefix == "get.")
2713  get_methods[mname.substr (4)] =
2714  make_fcn_handle (*mit, full_class_name + ">" + mname);
2715  else if (mprefix == "set.")
2716  set_methods[mname.substr (4)] =
2717  make_fcn_handle (*mit, full_class_name + ">" + mname);
2718  else
2719  {
2720  cdef_method meth = make_method (retval, mname, *mit);
2721 
2722 #if DEBUG_TRACE
2723  std::cerr << (mname == class_name ? "constructor"
2724  : "method")
2725  << ": " << mname << std::endl;
2726 #endif
2727 
2728  for (std::map<std::string, octave_value>::iterator
2729  ait = amap.begin (); ait != amap.end (); ++ait)
2730  meth.put (ait->first, ait->second);
2731 
2732  retval.install_method (meth);
2733  }
2734  }
2735  }
2736  }
2737 
2738  if (is_at_folder)
2739  {
2740  // Look for all external methods visible on octave path at the
2741  // time of loading of the class.
2742  //
2743  // FIXME: This is an "extension" to Matlab behavior, which only
2744  // looks in the @-folder containing the original classdef
2745  // file. However, this is easier to implement it that way at
2746  // the moment.
2747 
2748  std::list<std::string> external_methods =
2749  load_path::methods (full_class_name);
2750 
2751  for (std::list<std::string>::const_iterator
2752  it = external_methods.begin ();
2753  it != external_methods.end ();
2754  ++it)
2755  {
2756  // FIXME: should we issue a warning if the method is already
2757  // defined in the classdef file?
2758 
2759  if (*it != class_name
2760  && ! retval.find_method (*it, true).ok ())
2761  {
2762  // Create a dummy method that is used until the actual
2763  // method is loaded.
2764 
2766 
2767  fcn->stash_function_name (*it);
2768 
2769  cdef_method meth = make_method (retval, *it,
2770  octave_value (fcn));
2771 
2772  retval.install_method (meth);
2773  }
2774  }
2775  }
2776 
2777  // Property blocks
2778 
2779  // FIXME: default property expression should be able to call static
2780  // methods of the class being constructed. A restricted CLASSNAME
2781  // symbol should be added to the scope before evaluating default
2782  // value expressions.
2783 
2784  std::list<tree_classdef_properties_block *> pb_list
2785  = b->properties_list ();
2786 
2787  for (tree_classdef_body::properties_list_iterator it = pb_list.begin ();
2788  it != pb_list.end (); ++it)
2789  {
2790  std::map<std::string, octave_value> amap;
2791 
2792 #if DEBUG_TRACE
2793  std::cerr << "property block" << std::endl;
2794 #endif
2795 
2796  // Property attributes
2797 
2798  if ((*it)->attribute_list ())
2799  {
2801  (*it)->attribute_list ()->begin ();
2802  ait != (*it)->attribute_list ()->end (); ++ait)
2803  {
2804  std::string aname = (*ait)->ident ()->name ();
2805  octave_value avalue = compute_attribute_value (*ait);
2806 
2807 #if DEBUG_TRACE
2808  std::cerr << "property attribute: " << aname << " = "
2809  << attribute_value_to_string (*ait, avalue)
2810  << std::endl;
2811 #endif
2812 
2813  if (aname == "Access")
2814  {
2815  amap["GetAccess"] = avalue;
2816  amap["SetAccess"] = avalue;
2817  }
2818  else
2819  amap[aname] = avalue;
2820  }
2821  }
2822 
2823  // Properties
2824 
2825  if ((*it)->element_list ())
2826  {
2828  (*it)->element_list ()->begin ();
2829  pit != (*it)->element_list ()->end (); ++pit)
2830  {
2831  std::string prop_name = (*pit)->ident ()->name ();
2832 
2833  cdef_property prop = ::make_property (retval, prop_name);
2834 
2835 #if DEBUG_TRACE
2836  std::cerr << "property: " << (*pit)->ident ()->name ()
2837  << std::endl;
2838 #endif
2839 
2840  if ((*pit)->expression ())
2841  {
2842  octave_value pvalue = (*pit)->expression ()->rvalue1 ();
2843 
2844 #if DEBUG_TRACE
2845  std::cerr << "property default: "
2846  << attribute_value_to_string (*pit, pvalue)
2847  << std::endl;
2848 #endif
2849 
2850  prop.put ("DefaultValue", pvalue);
2851  }
2852 
2853  // Install property attributes. This is done before assigning
2854  // the property accessors so we can do validationby using
2855  // cdef_property methods.
2856 
2857  for (std::map<std::string, octave_value>::iterator ait = amap.begin ();
2858  ait != amap.end (); ++ait)
2859  prop.put (ait->first, ait->second);
2860 
2861  // Install property access methods, if any. Remove the
2862  // accessor methods from the temporary storage map, so we can
2863  // detect which ones are invalid and do not correspond to a
2864  // defined property.
2865 
2866  std::map<std::string, octave_value>::iterator git =
2867  get_methods.find (prop_name);
2868 
2869  if (git != get_methods.end ())
2870  {
2871  make_function_of_class (retval, git->second);
2872  prop.put ("GetMethod", git->second);
2873  get_methods.erase (git);
2874  }
2875 
2876  std::map<std::string, octave_value>::iterator sit =
2877  set_methods.find (prop_name);
2878 
2879  if (sit != set_methods.end ())
2880  {
2881  make_function_of_class (retval, sit->second);
2882  prop.put ("SetMethod", sit->second);
2883  set_methods.erase (sit);
2884  }
2885 
2886  retval.install_property (prop);
2887  }
2888  }
2889  }
2890  }
2891 
2892  return retval;
2893 }
2894 
2897 {
2899 
2900  return p;
2901 }
2902 
2905  bool do_check_access,
2906  const std::string& who)
2907 {
2909 
2910  if (do_check_access && ! check_get_access ())
2911  err_property_access (who, wrap (), false);
2912 
2913  if (! obj.is_constructed ())
2914  {
2915  cdef_class cls (to_cdef (get ("DefiningClass")));
2916 
2917  if (! obj.is_partially_constructed_for (cls))
2918  error ("cannot reference properties of class `%s' for non-constructed object",
2919  cls.get_name ().c_str ());
2920  }
2921 
2922  octave_value get_fcn = get ("GetMethod");
2923 
2924  // FIXME: should check whether we're already in get accessor method
2925 
2926  if (get_fcn.is_empty () || is_method_executing (get_fcn, obj))
2927  retval = obj.get (get ("Name").string_value ());
2928  else
2929  {
2931 
2932  args(0) = to_ov (obj);
2933 
2934  args = execute_ov (get_fcn, args, 1);
2935 
2936  retval = args(0);
2937  }
2938 
2939  return retval;
2940 }
2941 
2944  const std::string& who)
2945 {
2946  if (do_check_access && ! check_get_access ())
2947  err_property_access (who, wrap (), false);
2948 
2949  return get ("DefaultValue");
2950 }
2951 
2952 bool
2954 {
2955  // FIXME: implement
2956  return false;
2957 }
2958 
2959 void
2961  const octave_value& val,
2962  bool do_check_access,
2963  const std::string& who)
2964 {
2965  if (do_check_access && ! check_set_access ())
2966  err_property_access (who, wrap (), true);
2967 
2968  if (! obj.is_constructed ())
2969  {
2970  cdef_class cls (to_cdef (get ("DefiningClass")));
2971 
2972  if (! obj.is_partially_constructed_for (cls))
2973  error ("cannot reference properties of class `%s' for non-constructed object",
2974  cls.get_name ().c_str ());
2975  }
2976 
2977  octave_value set_fcn = get ("SetMethod");
2978 
2979  if (set_fcn.is_empty () || is_method_executing (set_fcn, obj))
2980  obj.put (get ("Name").string_value (), val);
2981  else
2982  {
2984 
2985  args(0) = to_ov (obj);
2986  args(1) = val;
2987 
2988  args = execute_ov (set_fcn, args, 1);
2989 
2990  if (args.length () > 0 && args(0).is_defined ())
2991  {
2992  if (args (0).is_classdef_object ())
2993  {
2994  cdef_object new_obj = to_cdef (args(0));
2995 
2996  obj = new_obj;
2997  }
2998  else
2999  ::warning ("set-method of property `%s' returned a non-classdef object",
3000  get_name ().c_str ());
3001  }
3002  }
3003 }
3004 
3005 bool
3007 {
3008  cdef_class cls (to_cdef (get ("DefiningClass")));
3009 
3010  return ::check_access (cls, get ("GetAccess"), "",
3011  get_name (), false);
3012 
3013  return false;
3014 }
3015 
3016 bool
3018 {
3019  cdef_class cls (to_cdef (get ("DefiningClass")));
3020 
3021  return ::check_access (cls, get ("SetAccess"), "",
3022  get_name (), true);
3023 
3024  return false;
3025 }
3026 
3027 void
3029 {
3030  if (is_external ())
3031  {
3032  if (is_dummy_method (function))
3033  {
3034  std::string name = get_name ();
3035  std::string cls_name = dispatch_type;
3036  std::string pack_name;
3037 
3038  size_t pos = cls_name.rfind ('.');
3039 
3040  if (pos != std::string::npos)
3041  {
3042  pack_name = cls_name.substr (0, pos);
3043  cls_name = cls_name.substr (pos + 1);
3044  }
3045 
3046  std::string dir_name;
3047  std::string file_name = load_path::find_method (cls_name, name,
3048  dir_name, pack_name);
3049 
3050  if (! file_name.empty ())
3051  {
3052  octave_function *fcn = load_fcn_from_file (file_name, dir_name,
3053  dispatch_type,
3054  pack_name);
3055 
3056  if (fcn)
3057  {
3058  function = octave_value (fcn);
3059 
3060  make_function_of_class (dispatch_type, function);
3061  }
3062  }
3063  }
3064  else
3065  {
3066  // FIXME: check out-of-date status
3067  }
3068 
3069  if (is_dummy_method (function))
3070  error ("no definition found for method `%s' of class `%s'",
3071  get_name ().c_str (), dispatch_type.c_str ());
3072  }
3073 }
3074 
3077  int nargout, bool do_check_access,
3078  const std::string& who)
3079 {
3081 
3082  if (do_check_access && ! check_access ())
3083  err_method_access (who, wrap ());
3084 
3085  if (get ("Abstract").bool_value ())
3086  error ("%s: cannot execute abstract method",
3087  get ("Name").string_value ().c_str ());
3088 
3089  check_method ();
3090 
3091  if (function.is_defined ())
3092  retval = execute_ov (function, args, nargout);
3093 
3094  return retval;
3095 }
3096 
3099  const octave_value_list& args,
3100  int nargout, bool do_check_access,
3101  const std::string& who)
3102 {
3104 
3105  if (do_check_access && ! check_access ())
3106  err_method_access (who, wrap ());
3107 
3108  if (get ("Abstract").bool_value ())
3109  error ("%s: cannot execute abstract method",
3110  get ("Name").string_value ().c_str ());
3111 
3112  check_method ();
3113 
3114  if (function.is_defined ())
3115  {
3116  octave_value_list new_args;
3117 
3118  new_args.resize (args.length () + 1);
3119 
3120  new_args(0) = to_ov (obj);
3121  for (int i = 0; i < args.length (); i++)
3122  new_args(i+1) = args(i);
3123 
3124  retval = execute_ov (function, new_args, nargout);
3125  }
3126 
3127  return retval;
3128 }
3129 
3130 bool
3132 {
3133  if (function.is_function())
3134  return function.function_value ()->is_classdef_constructor ();
3135 
3136  return false;
3137 }
3138 
3139 bool
3141 {
3142  cdef_class cls (to_cdef (get ("DefiningClass")));
3143 
3144  return ::check_access (cls, get ("Access"), get_name ());
3145 }
3146 
3149  (const std::string& type, const std::list<octave_value_list>& idx,
3150  int nargout)
3151 {
3153 
3154  switch (type[0])
3155  {
3156  case '(':
3157  retval = execute (idx.front (), type.length () > 1 ? 1 : nargout, true);
3158  break;
3159 
3160  default:
3161  error ("invalid meta.method indexing");
3162  break;
3163  }
3164 
3165  if (type.length () > 1 && idx.size () > 1 && ! retval.empty ())
3166  retval = retval(0).next_subsref (nargout, type, idx, 1);
3167 
3168  return retval;
3169 }
3170 
3171 static cdef_package
3173 {
3174  return cdef_manager::find_package (name);
3175 }
3176 
3177 static octave_value_list
3178 package_fromName (const octave_value_list& args, int /* nargout */)
3179 {
3181 
3182  if (args.length () != 1)
3183  error ("fromName: invalid number of parameters");
3184 
3185  std::string name = args(0).xstring_value ("fromName: PACKAGE_NAME must be a string");
3186 
3187  retval(0) = to_ov (lookup_package (name));
3188 
3189  return retval;
3190 }
3191 
3192 static octave_value_list
3193 package_get_classes (const octave_value_list& args, int /* nargout */)
3194 {
3196 
3197  if (args.length () == 1 && args(0).type_name () == "object"
3198  && args(0).class_name () == "meta.package")
3199  {
3200  cdef_package pack (to_cdef (args(0)));
3201 
3202  retval(0) = pack.get_classes ();
3203  }
3204 
3205  return retval;
3206 }
3207 
3208 static octave_value_list
3209 package_get_functions (const octave_value_list& args, int /* nargout */)
3210 {
3212 
3213  if (args.length () == 0 && args(0).type_name () == "object"
3214  && args(0).class_name () == "meta.package")
3215  {
3216  cdef_package pack (to_cdef (args(0)));
3217 
3218  retval(0) = pack.get_functions ();
3219  }
3220 
3221  return retval;
3222 }
3223 
3224 static octave_value_list
3225 package_get_packages (const octave_value_list& args, int /* nargout */)
3226 {
3228 
3229  if (args.length () == 0 && args(0).type_name () == "object"
3230  && args(0).class_name () == "meta.package")
3231  {
3232  cdef_package pack (to_cdef (args(0)));
3233 
3234  retval(0) = pack.get_packages ();
3235  }
3236 
3237  return retval;
3238 }
3239 
3240 static octave_value_list
3241 package_getAllPackages (const octave_value_list& /* args */, int /* nargout */)
3242 {
3243  std::map<std::string, cdef_package> toplevel_packages;
3244 
3245  std::list<std::string> names = load_path::get_all_package_names ();
3246 
3247  toplevel_packages["meta"] = cdef_manager::find_package ("meta", false,
3248  false);
3249 
3250  for (std::list<std::string>::const_iterator it = names.begin ();
3251  it != names.end (); ++it)
3252  toplevel_packages[*it] = cdef_manager::find_package (*it, false, true);
3253 
3254  Cell c (toplevel_packages.size (), 1);
3255 
3256  int i = 0;
3257 
3258  for (std::map<std::string, cdef_package>::const_iterator it =
3259  toplevel_packages.begin ();
3260  it != toplevel_packages.end (); ++it)
3261  c(i++,0) = to_ov (it->second);
3262 
3263  return octave_value_list (octave_value (c));
3264 }
3265 
3266 void
3268  const std::string& nm)
3269 {
3270  class_map[nm] = cls;
3271 
3272  member_count++;
3273 }
3274 
3275 void
3277  const std::string& nm)
3278 {
3279  function_map[nm] = fcn;
3280 }
3281 
3282 void
3284  const std::string& nm)
3285 {
3286  package_map[nm] = pack;
3287 
3288  member_count++;
3289 }
3290 
3291 template <typename T1, typename T2>
3292 Cell
3293 map2Cell (const std::map<T1, T2>& m)
3294 {
3295  Cell retval (1, m.size ());
3296  int i = 0;
3297 
3298  for (typename std::map<T1, T2>::const_iterator it = m.begin ();
3299  it != m.end (); ++it, ++i)
3300  {
3301  retval(i) = to_ov (it->second);
3302  }
3303 
3304  return retval;
3305 }
3306 
3307 Cell
3309 { return map2Cell (class_map); }
3310 
3311 Cell
3313 { return map2Cell (function_map); }
3314 
3315 Cell
3317 { return map2Cell (package_map); }
3318 
3321 {
3322  std::string symbol_name = get_name () + "." + nm;
3323 
3324  return symbol_table::find (symbol_name, octave_value_list (), true, false);
3325 }
3326 
3329  (const std::string& type, const std::list<octave_value_list>& idx,
3330  int nargout)
3331 {
3333 
3334  switch (type[0])
3335  {
3336  case '.':
3337  {
3338  if (idx.front ().length () != 1)
3339  error ("invalid meta.package indexing");
3340 
3341  std::string nm = idx.front ()(0).xstring_value ("invalid meta.package indexing, expected a symbol name");
3342 
3343 #if DEBUG_TRACE
3344  std::cerr << "meta.package query: " << nm << std::endl;
3345 #endif
3346 
3347  octave_value o = find (nm);
3348 
3349  if (! o.is_defined ())
3350  error ("member `%s' in package `%s' does not exist",
3351  nm.c_str (), get_name ().c_str ());
3352 
3353  if (o.is_function ())
3354  {
3356 
3357  // NOTE: the case where the package query is the last
3358  // part of this subsref index is handled in the parse
3359  // tree, because there is some logic to handle magic
3360  // "end" that makes it impossible to execute the
3361  // function call at this stage.
3362 
3363  if (type.size () > 1
3364  && ! fcn->is_postfix_index_handled (type[1]))
3365  {
3366  octave_value_list tmp_args;
3367 
3368  retval = o.do_multi_index_op (nargout,
3369  tmp_args);
3370  }
3371  else
3372  retval(0) = o;
3373 
3374  if (type.size () > 1 && idx.size () > 1)
3375  retval = retval(0).next_subsref (nargout, type,
3376  idx, 1);
3377  }
3378  else if (type.size () > 1 && idx.size () > 1)
3379  retval = o.next_subsref (nargout, type, idx, 1);
3380  else
3381  retval(0) = o;
3382  }
3383  break;
3384 
3385  default:
3386  error ("invalid meta.package indexing");
3387  break;
3388  }
3389 
3390  return retval;
3391 }
3392 
3393 void
3395 {
3396  // FIXME: Do we really want to unregister the package, as it
3397  // could still be referenced by classes or sub-packages?
3398  // If the package object is recreated later on, it won't
3399  // match the one already referenced by those classes or
3400  // sub-packages.
3401 
3402  //cdef_manager::unregister_package (wrap ());
3403 }
3404 
3409 
3411 
3412 void
3414 {
3416 
3417  // bootstrap
3418  cdef_class handle = make_class ("handle");
3419  cdef_class meta_class = cdef_class::_meta_class = make_meta_class ("meta.class", handle);
3420  handle.set_class (meta_class);
3421  meta_class.set_class (meta_class);
3422 
3423  // meta classes
3424  cdef_class meta_property = cdef_class::_meta_property = make_meta_class ("meta.property", handle);
3425  cdef_class meta_method = cdef_class::_meta_method = make_meta_class ("meta.method", handle);
3426  cdef_class meta_package = cdef_class::_meta_package = make_meta_class ("meta.package", handle);
3427 
3428  cdef_class meta_event = make_meta_class ("meta.event", handle);
3429  cdef_class meta_dynproperty = make_meta_class ("meta.dynamicproperty", handle);
3430 
3431  // meta.class properties
3432  meta_class.install_property (make_attribute (meta_class, "Abstract"));
3433  meta_class.install_property (make_attribute (meta_class, "ConstructOnLoad"));
3434  meta_class.install_property (make_property (meta_class, "ContainingPackage"));
3435  meta_class.install_property (make_property (meta_class, "Description"));
3436  meta_class.install_property (make_property (meta_class, "DetailedDescription"));
3437  meta_class.install_property (make_property (meta_class, "Events"));
3438  meta_class.install_property (make_attribute (meta_class, "HandleCompatible"));
3439  meta_class.install_property (make_attribute (meta_class, "Hidden"));
3440  meta_class.install_property
3441  (make_property (meta_class, "InferiorClasses",
3442  make_fcn_handle (class_get_inferiorclasses, "meta.class>get.InferiorClasses"),
3443  "public", Matrix (), "private"));
3444  meta_class.install_property
3445  (make_property (meta_class, "Methods",
3446  make_fcn_handle (class_get_methods, "meta.class>get.Methods"),
3447  "public", Matrix (), "private"));
3448  meta_class.install_property
3449  (make_property (meta_class, "MethodList",
3450  make_fcn_handle (class_get_methods, "meta.class>get.MethodList"),
3451  "public", Matrix (), "private"));
3452  meta_class.install_property (make_attribute (meta_class, "Name"));
3453  meta_class.install_property
3454  (make_property (meta_class, "Properties",
3455  make_fcn_handle (class_get_properties, "meta.class>get.Properties"),
3456  "public", Matrix (), "private"));
3457  meta_class.install_property
3458  (make_property (meta_class, "PropertyList",
3459  make_fcn_handle (class_get_properties, "meta.class>get.PropertyList"),
3460  "public", Matrix (), "private"));
3461  meta_class.install_property (make_attribute (meta_class, "Sealed"));
3462  meta_class.install_property
3463  (make_property (meta_class, "SuperClasses",
3464  make_fcn_handle (class_get_superclasses, "meta.class>get.SuperClasses"),
3465  "public", Matrix (), "private"));
3466  meta_class.install_property
3467  (make_property (meta_class, "SuperClassList",
3468  make_fcn_handle (class_get_superclasses, "meta.class>get.SuperClassList"),
3469  "public", Matrix (), "private"));
3470  // meta.class methods
3471  meta_class.install_method (make_method (meta_class, "fromName", class_fromName,
3472  "public", true));
3473  meta_class.install_method (make_method (meta_class, "fevalStatic",
3475  "public", false));
3476  meta_class.install_method (make_method (meta_class, "getConstant",
3478  "public", false));
3479  meta_class.install_method (make_method (meta_class, "eq", class_eq));
3480  meta_class.install_method (make_method (meta_class, "ne", class_ne));
3481  meta_class.install_method (make_method (meta_class, "lt", class_lt));
3482  meta_class.install_method (make_method (meta_class, "le", class_le));
3483  meta_class.install_method (make_method (meta_class, "gt", class_gt));
3484  meta_class.install_method (make_method (meta_class, "ge", class_ge));
3485 
3486  // meta.method properties
3487  meta_method.install_property (make_attribute (meta_method, "Abstract"));
3488  meta_method.install_property (make_attribute (meta_method, "Access"));
3489  meta_method.install_property (make_attribute (meta_method, "DefiningClass"));
3490  meta_method.install_property (make_attribute (meta_method, "Description"));
3491  meta_method.install_property (make_attribute (meta_method, "DetailedDescription"));
3492  meta_method.install_property (make_attribute (meta_method, "Hidden"));
3493  meta_method.install_property (make_attribute (meta_method, "Name"));
3494  meta_method.install_property (make_attribute (meta_method, "Sealed"));
3495  meta_method.install_property (make_attribute (meta_method, "Static"));
3496 
3497  // meta.property properties
3498  meta_property.install_property (make_attribute (meta_property, "Name"));
3499  meta_property.install_property (make_attribute (meta_property, "Description"));
3500  meta_property.install_property (make_attribute (meta_property, "DetailedDescription"));
3501  meta_property.install_property (make_attribute (meta_property, "Abstract"));
3502  meta_property.install_property (make_attribute (meta_property, "Constant"));
3503  meta_property.install_property (make_attribute (meta_property, "GetAccess"));
3504  meta_property.install_property (make_attribute (meta_property, "SetAccess"));
3505  meta_property.install_property (make_attribute (meta_property, "Dependent"));
3506  meta_property.install_property (make_attribute (meta_property, "Transient"));
3507  meta_property.install_property (make_attribute (meta_property, "Hidden"));
3508  meta_property.install_property (make_attribute (meta_property, "GetObservable"));
3509  meta_property.install_property (make_attribute (meta_property, "SetObservable"));
3510  meta_property.install_property (make_attribute (meta_property, "GetMethod"));
3511  meta_property.install_property (make_attribute (meta_property, "SetMethod"));
3512  meta_property.install_property (make_attribute (meta_property, "DefiningClass"));
3513  meta_property.install_property
3514  (make_property (meta_property, "DefaultValue",
3515  make_fcn_handle (property_get_defaultvalue, "meta.property>get.DefaultValue"),
3516  "public", Matrix (), "private"));
3517  meta_property.install_property (make_attribute (meta_property, "HasDefault"));
3518  // meta.property events
3519  // FIXME: add events
3520 
3521  // handle methods
3522  handle.install_method (make_method (handle, "delete", handle_delete));
3523 
3524  // meta.package properties
3525  meta_package.install_property (make_attribute (meta_package, "Name"));
3526  meta_package.install_property (make_property (meta_package, "ContainingPackage"));
3527  meta_package.install_property
3528  (make_property (meta_package, "ClassList",
3529  make_fcn_handle (package_get_classes, "meta.package>get.ClassList"),
3530  "public", Matrix (), "private"));
3531  meta_package.install_property
3532  (make_property (meta_package, "Classes",
3533  make_fcn_handle (package_get_classes, "meta.package>get.Classes"),
3534  "public", Matrix (), "private"));
3535  meta_package.install_property
3536  (make_property (meta_package, "FunctionList",
3537  make_fcn_handle (package_get_functions, "meta.package>get.FunctionList"),
3538  "public", Matrix (), "private"));
3539  meta_package.install_property
3540  (make_property (meta_package, "Functions",
3541  make_fcn_handle (package_get_functions, "meta.package>get.Functions"),
3542  "public", Matrix (), "private"));
3543  meta_package.install_property
3544  (make_property (meta_package, "PackageList",
3545  make_fcn_handle (package_get_packages, "meta.package>get.PackageList"),
3546  "public", Matrix (), "private"));
3547  meta_package.install_property
3548  (make_property (meta_package, "Packages",
3549  make_fcn_handle (package_get_packages, "meta.package>get.Packages"),
3550  "public", Matrix (), "private"));
3551  meta_package.install_method (make_method (meta_package, "fromName", package_fromName,
3552  "public", true));
3553  meta_package.install_method (make_method (meta_package, "getAllPackages", package_getAllPackages,
3554  "public", true));
3555 
3556  // create "meta" package
3557  cdef_package package_meta = cdef_package::_meta = make_package ("meta");
3558  package_meta.install_class (meta_class, "class");
3559  package_meta.install_class (meta_property, "property");
3560  package_meta.install_class (meta_method, "method");
3561  package_meta.install_class (meta_package, "package");
3562  package_meta.install_class (meta_event, "event");
3563  package_meta.install_class (meta_dynproperty, "dynproperty");
3564 
3565  // install built-in classes into the symbol table
3567  ("meta.class", octave_value (meta_class.get_constructor_function ()));
3569  ("meta.method", octave_value (meta_method.get_constructor_function ()));
3571  ("meta.property", octave_value (meta_property.get_constructor_function ()));
3573  ("meta.package", octave_value (meta_package.get_constructor_function ()));
3575  ("meta.event", octave_value (meta_event.get_constructor_function ()));
3577  ("meta.dynproperty", octave_value (meta_dynproperty.get_constructor_function ()));
3578 }
3579 
3580 //----------------------------------------------------------------------------
3581 
3583 
3584 void
3586 {
3587  instance = new cdef_manager ();
3588 
3589  if (instance)
3590  singleton_cleanup_list::add (cleanup_instance);
3591 }
3592 
3593 cdef_class
3595  bool error_if_not_found, bool load_if_not_found)
3596 {
3597  std::map<std::string, cdef_class>::iterator it = all_classes.find (name);
3598 
3599  if (it == all_classes.end ())
3600  {
3601  if (load_if_not_found)
3602  {
3603  octave_value ov_cls;
3604 
3605  size_t pos = name.rfind ('.');
3606 
3607  if (pos == std::string::npos)
3608  ov_cls = symbol_table::find (name);
3609  else
3610  {
3611  std::string pack_name = name.substr (0, pos);
3612 
3613  cdef_package pack = do_find_package (pack_name, false, true);
3614 
3615  if (pack.ok ())
3616  ov_cls = pack.find (name.substr (pos+1));
3617  }
3618 
3619  if (ov_cls.is_defined ())
3620  it = all_classes.find (name);
3621  }
3622  }
3623 
3624  if (it == all_classes.end ())
3625  {
3626  if (error_if_not_found)
3627  error ("class not found: %s", name.c_str ());
3628  }
3629  else
3630  {
3631  cdef_class cls = it->second;
3632 
3633  if (! cls.is_builtin ())
3634  cls = lookup_class (cls);
3635 
3636  if (cls.ok ())
3637  return cls;
3638  else
3639  all_classes.erase (it);
3640  }
3641 
3642  return cdef_class ();
3643 }
3644 
3647  const std::string& class_name)
3648 {
3649  octave_function *retval = 0;
3650 
3651  cdef_class cls = find_class (class_name, false, false);
3652 
3653  if (cls.ok ())
3654  {
3655  cdef_method meth = cls.find_method (method_name);
3656 
3657  if (meth.ok ())
3658  retval = new octave_classdef_meta (meth);
3659  }
3660 
3661  return retval;
3662 }
3663 
3666  bool error_if_not_found,
3667  bool load_if_not_found)
3668 {
3670 
3671  std::map<std::string, cdef_package>::const_iterator it
3672  = all_packages.find (name);
3673 
3674  if (it != all_packages.end ())
3675  {
3676  retval = it->second;
3677 
3678  if (! retval.ok ())
3679  error ("invalid package `%s'", name.c_str ());
3680  }
3681  else
3682  {
3683  if (load_if_not_found && load_path::find_package (name))
3684  {
3685  size_t pos = name.find ('.');
3686 
3687  if (pos == std::string::npos)
3688  retval = make_package (name, "");
3689  else
3690  {
3691  std::string parent_name = name.substr (0, pos);
3692 
3693  retval = make_package (name, parent_name);
3694  }
3695  }
3696  else if (error_if_not_found)
3697  error ("unknown package `%s'", name.c_str ());
3698  }
3699 
3700  return retval;
3701 }
3702 
3705 {
3706  octave_function* retval = 0;
3707 
3708  cdef_package pack = find_package (pack_name, false);
3709 
3710  if (pack.ok ())
3711  retval = new octave_classdef_meta (pack);
3712 
3713  return retval;
3714 }
3715 
3716 //----------------------------------------------------------------------------
3717 
3718 DEFUN (__meta_get_package__, args, ,
3719  doc: /* -*- texinfo -*-
3720 @deftypefn {} {} __meta_get_package__ ()
3721 Undocumented internal function.
3722 @end deftypefn */)
3723 {
3724  if (args.length () != 1)
3725  print_usage ();
3726 
3727  std::string cname = args(0).xstring_value ("PACKAGE_NAME must be a string");
3728 
3729  return to_ov (lookup_package (cname));
3730 }
3731 
3732 DEFUN (__superclass_reference__, args, ,
3733  doc: /* -*- texinfo -*-
3734 @deftypefn {} {} __superclass_reference__ ()
3735 Undocumented internal function.
3736 @end deftypefn */)
3737 {
3738  return ovl (new octave_classdef_superclass_ref (args));
3739 }
3740 
3741 DEFUN (__meta_class_query__, args, ,
3742  doc: /* -*- texinfo -*-
3743 @deftypefn {} {} __meta_class_query__ ()
3744 Undocumented internal function.
3745 @end deftypefn */)
3746 {
3747 #if DEBUG_TRACE
3748  std::cerr << "__meta_class_query__ ("
3749  << args(0).string_value () << ")"
3750  << std::endl;
3751 #endif
3752 
3753  if (args.length () != 1)
3754  print_usage ();
3755 
3756  std::string cls = args(0).xstring_value ("CLASS_NAME must be a string");
3757 
3758  return to_ov (lookup_class (cls));
3759 }
3760 
3761 DEFUN (metaclass, args, ,
3762  doc: /* -*- texinfo -*-
3763 @deftypefn {} {} metaclass (obj)
3764 Returns the meta.class object corresponding to the class of @var{obj}.
3765 @end deftypefn */)
3766 {
3767  if (args.length () != 1)
3768  print_usage ();
3769 
3770  cdef_object obj = to_cdef (args(0));
3771 
3772  return to_ov (obj.get_class ());
3773 }
3774 
3775 /*
3776 ;;; Local Variables: ***
3777 ;;; mode: C++ ***
3778 ;;; End: ***
3779 */
static octave_value_list class_ne(const octave_value_list &args, int)
Definition: ov-classdef.cc:610
void visit_postfix_expression(tree_postfix_expression &)
void visit_return_command(tree_return_command &)
bool called_from_builtin(void)
Definition: ov-base.cc:1517
void warning_with_id(const char *id, const char *fmt,...)
Definition: error.cc:803
static void install_built_in_function(const std::string &name, const octave_value &fcn)
Definition: symtab.h:1644
void set_value(cdef_object &obj, const octave_value &val, bool do_check_access=true, const std::string &who="")
virtual bool is_classdef_constructor(const std::string &="") const
Definition: ov-fcn.h:91
octave_value find(const std::string &nm)
Definition: ov-classdef.h:1379
bool is_static(void) const
Definition: ov-classdef.h:1141
Definition: Cell.h:37
void visit_argument_list(tree_argument_list &)
void visit_unwind_protect_command(tree_unwind_protect_command &)
octave_refcount< octave_idx_type > count
Definition: ov-base.h:843
void visit_index_expression(tree_index_expression &t)
void visit_cell(tree_cell &)
cdef_class(void)
Definition: ov-classdef.h:765
void visit_octave_user_function(octave_user_function &)
Cell get_properties(int mode=property_normal)
Definition: ov-classdef.h:804
bool is_direct_superclass(const cdef_class &clsa, const cdef_class &clsb)
Definition: ov-classdef.cc:246
octave_function * 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:8260
octave_value subsref(const std::string &type, const std::list< octave_value_list > &idx)
Definition: ov.h:417
std::string get_name(void) const
Definition: ov-classdef.h:1139
std::list< tree_classdef_methods_block * >::iterator methods_list_iterator
Definition: pt-classdef.h:490
static 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=false)
Definition: ov-classdef.cc:306
void visit_funcall(tree_funcall &t)
cdef_meta_object object
octave_value get_function(void) const
Definition: ov-classdef.h:1146
void install_method(const cdef_method &meth)
Definition: ov-classdef.h:794
dim_vector dims(void) const
Definition: ov-classdef.h:362
virtual bool is_postfix_index_handled(char type) const
Definition: ov-fcn.h:181
octave_value_list subsref(const std::string &type, const std::list< octave_value_list > &idx, int nargout)
static octave_value_list class_gt(const octave_value_list &args, int)
Definition: ov-classdef.cc:607
string_vector get_names(void)
octave_value_list(* fcn)(const octave_value_list &, int)
Definition: ov-builtin.h:47
virtual bool is_class_method(const std::string &="") const
Definition: ov-fcn.h:94
static octave_value_list class_le(const octave_value_list &args, int)
Definition: ov-classdef.cc:606
Cell get_functions(void) const
octave_value_list subsref(const std::string &type, const std::list< octave_value_list > &idx, int nargout, size_t &skip, const cdef_class &context, bool auto_add=false)
Definition: ov-classdef.h:255
tree_parameter_list * parameter_list(void)
Definition: ov-usr-fcn.h:377
void run_constructor(cdef_object &obj, const octave_value_list &args)
std::string name(void)
Definition: pt-decl.h:89
OCTAVE_EXPORT octave_value_list isa nd deftypefn *return ovl(args(0).is_integer_type())
void print_with_name(std::ostream &os, const std::string &name, bool print_padding=true)
Definition: ov-classdef.cc:988
octave_value_list subsref(const std::string &type, const std::list< octave_value_list > &idx, int nargout, size_t &skip, const cdef_class &context, bool auto_add)
OCTINTERP_API void print_usage(void)
Definition: defun.cc:52
octave_map map_value(void) const
void set_value(cdef_object &obj, const octave_value &val, bool do_check_access=true, const std::string &who="")
Definition: ov-classdef.h:999
static std::list< std::string > methods(const std::string &class_name, const std::string &pack_name="")
Definition: load-path.h:118
bool is_function(void) const
Definition: ov.h:711
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:363
void visit_persistent_command(tree_persistent_command &)
identity matrix If supplied two scalar respectively For allows like xample val
Definition: data.cc:5068
void install_class(const cdef_class &cls, const std::string &nm)
void set_pos_if_unset(octave_idx_type nd_arg, octave_idx_type dim_arg)
octave_idx_type length(void) const
Definition: ovl.h:96
void accept(tree_walker &tw)
Definition: pt-stmt.cc:324
Return the CPU time used by your Octave session The first output is the total time spent executing your process and is equal to the sum of second and third which are the number of CPU seconds spent executing in user mode and the number of CPU seconds spent executing in system mode
Definition: data.cc:6386
friend void install_classdef(void)
octave_value_list execute_ov(octave_value val, const octave_value_list &args, int nargout)
Definition: ov-classdef.cc:148
static octave_value_list class_lt(const octave_value_list &args, int)
Definition: ov-classdef.cc:605
bool is_defined(void) const
Definition: ov.h:536
bool is_classdef_constructor(const std::string &cname="") const
Definition: ov-usr-fcn.h:340
void find_properties(std::map< std::string, cdef_property > &props, int mode=0)
bool is_classdef_constructor(const std::string &cname="") const
void mark_for_construction(const cdef_class &cls)
Definition: ov-classdef.h:276
octave_function * get_method_function(const std::string &nm)
void put(const std::string &pname, const octave_value &val)
Definition: ov-classdef.h:405
void visit_switch_case_list(tree_switch_case_list &)
static const cdef_class & meta_package(void)
Definition: ov-classdef.h:865
static bool in_class_method(const cdef_class &cls)
Definition: ov-classdef.cc:298
Array< cdef_object > array
Definition: ov-classdef.h:380
void find_methods(std::map< std::string, cdef_method > &meths, bool only_inherited)
void visit_statement(tree_statement &t)
static const cdef_class & meta_property(void)
Definition: ov-classdef.h:863
#define DEFUN(name, args_name, nargout_name, doc)
Definition: defun.h:46
void error(const char *fmt,...)
Definition: error.cc:570
static octave_value_list class_get_inferiorclasses(const octave_value_list &args, int)
Definition: ov-classdef.cc:502
tree_classdef_body * body(void)
Definition: pt-classdef.h:619
std::string name(void) const
Definition: ov-fcn.h:163
#define META_CLASS_CMP(OP, CLSA, CLSB, FUN)
Definition: ov-classdef.cc:583
void install_function(const octave_value &fcn, const std::string &nm)
void indent(std::ostream &os) const
Definition: ov-base.cc:1362
static std::list< cdef_class > lookup_classes(const Cell &cls_list)
Definition: ov-classdef.cc:190
octave_value_list do_multi_index_op(int nargout, const octave_value_list &idx)
cdef_object & to_cdef_ref(const octave_value &val)
Definition: ov-classdef.h:1512
static octave_function * current(void)
Definition: call-stack.h:108
static octave_value_list class_getConstant(const octave_value_list &args, int)
Definition: ov-classdef.cc:556
std::list< tree_classdef_methods_block * > methods_list(void)
Definition: pt-classdef.h:553
octave_value_list execute(const octave_value_list &args, int nargout, bool do_check_access=true, const std::string &who="")
static octave_value_list class_get_properties(const octave_value_list &args, int)
Definition: ov-classdef.cc:250
void visit_identifier(tree_identifier &)
std::map< cdef_class, std::list< cdef_class > > ctor_list
Definition: ov-classdef.h:444
tree_identifier * ident(void)
Definition: pt-classdef.h:615
octave_function * function_value(bool=false)
static void register_class(const cdef_class &cls)
Definition: ov-classdef.h:1570
static cdef_package find_package(const std::string &name, bool error_if_not_found=true, bool load_if_not_found=true)
Definition: ov-classdef.h:1551
std::list< tree_classdef_superclass * >::iterator iterator
Definition: base-list.h:40
bool is_cell(void) const
Definition: ov.h:545
void visit_statement_list(tree_statement_list &t)
static void make_function_of_class(const std::string &class_name, const octave_value &fcn)
Definition: ov-classdef.cc:99
bool is_constructed(void) const
Definition: ov-classdef.h:437
OCTAVE_EXPORT octave_value_list return the number of command line arguments passed to Octave If called with the optional argument the function t
Definition: ov-usr-fcn.cc:935
static 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:99
bool is_constructor(void) const
Definition: ov-classdef.h:1149
static std::string get_base_name(const std::string &nm)
Definition: ov-classdef.cc:88
tree_expression * expression(void)
Definition: pt-idx.h:74
bool is_postfix_index_handled(char type) const
bool is_recursive_set(const cdef_object &obj) const
void visit_parameter_list(tree_parameter_list &)
s
Definition: file-io.cc:2682
static cdef_package make_package(const std::string &nm, const std::string &parent="")
Definition: ov-classdef.cc:797
octave_value_list subsref(const std::string &type, const std::list< octave_value_list > &idx, int nargout)
virtual string_vector map_keys(void) const
octave_value_list meta_subsref(const std::string &type, const std::list< octave_value_list > &idx, int nargout)
void fill_empty_values(void)
Definition: ov-classdef.h:383
i e
Definition: data.cc:2724
void newline(std::ostream &os) const
Definition: ov-base.cc:1381
cdef_class do_find_class(const std::string &name, bool error_if_not_found, bool load_if_not_found)
static octave_value_list class_get_methods(const octave_value_list &args, int)
Definition: ov-classdef.cc:469
bool is_partially_constructed_for(const cdef_class &cls) const
std::string class_name(void) const
Definition: ov-classdef.h:1476
bool check_get_access(void) const
static octave_value varval(const std::string &name, scope_id scope=xcurrent_scope, context_id context=xdefault_context)
Definition: symtab.h:1373
static octave_value_list handle_delete(const octave_value_list &, int)
Definition: ov-classdef.cc:633
Array< cdef_object > array_value(void) const
Definition: ov-classdef.h:246
std::string obj_name
void visit_global_command(tree_global_command &)
std::map< std::string, cdef_property >::iterator property_iterator
Definition: ov-classdef.h:751
octave_function * fcn
Definition: ov-class.cc:1743
std::string dispatch_class(void) const
Definition: ov-fcn.h:103
void print_raw(std::ostream &os, bool pr_as_read_syntax=false) const
Definition: ov-classdef.cc:970
static octave_value compute_attribute_value(tree_classdef_attribute *t)
octave_value subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
std::list< tree_classdef_properties_block * >::iterator properties_list_iterator
Definition: pt-classdef.h:487
void initialize_object(cdef_object &obj)
Definition: ov-classdef.h:846
std::map< std::string, cdef_property >::const_iterator property_const_iterator
Definition: ov-classdef.h:752
bool is_handle_object(void) const
Definition: ov-classdef.h:242
bool is_constructed_for(const cdef_class &cls) const
bool is_array(void) const
Definition: ov-classdef.h:238
calling an anonymous function involves an overhead quite comparable to the overhead of an m file function Passing a handle to a built in function is because the interpreter is not involved in the internal loop For a
Definition: cellfun.cc:398
void mark_for_construction(const cdef_class &)
Cell cell_value(void) const
Definition: ov.cc:1687
octave_classdef_meta(const cdef_meta_object &obj)
JNIEnv void * args
Definition: ov-java.cc:67
void install_method(const cdef_method &meth)
virtual octave_value undef_subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
Definition: ov-base.cc:347
virtual cdef_class get_class(void) const
Definition: ov-classdef.h:1166
const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
Definition: Array.h:439
void install_property(const cdef_property &prop)
octave_value_list do_multi_index_op(int nargout, const octave_value_list &idx)
Definition: ov.cc:1527
cdef_class get_class(void) const
Definition: ov-classdef.h:1180
std::string get_name(void) const
Definition: ov-classdef.h:1010
Cell get_functions(void) const
Definition: ov-classdef.h:1371
octave_value value(void) const
Definition: oct-lvalue.cc:83
void install_class(const cdef_class &cls, const std::string &nm)
Definition: ov-classdef.h:1359
static octave_value_list class_fromName(const octave_value_list &args, int)
Definition: ov-classdef.cc:520
OCTAVE_EXPORT octave_value_list any number nd example oindent prints the prompt xample Pick a any number!nd example oindent and waits for the user to enter a value The string entered by the user is evaluated as an so it may be a literal a variable name
Definition: input.cc:871
iterator end(void)
Definition: base-list.h:86
OCTAVE_EXPORT octave_value_list isdir nd deftypefn *std::string nm
Definition: utils.cc:941
octave_value subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
void visit_constant(tree_constant &)
octave_value_list property_get_defaultvalue(const octave_value_list &args, int)
Definition: ov-classdef.cc:613
octave_refcount< octave_idx_type > refcount
Definition: ov-classdef.h:169
ctor_analyzer(const std::string &ctor, const std::string &obj)
tree_expression * right_hand_side(void)
Definition: pt-assign.h:74
virtual octave_user_function * user_function_value(bool silent=false)
Definition: ov-base.cc:923
static cdef_class make_class(const std::string &name, const std::list< cdef_class > &super_list=std::list< cdef_class >())
Definition: ov-classdef.cc:643
static cdef_class make_meta_class(tree_classdef *t, bool is_at_folder=false)
OCTAVE_EXPORT octave_value_list return the number of command line arguments passed to Octave If called with the optional argument the function xample nargout(@histc)
Definition: ov-usr-fcn.cc:935
static octave_value to_ov(const std::list< cdef_class > &class_list)
Definition: ov-classdef.cc:205
cdef_method find_method(const std::string &nm, bool local=false)
Definition: ov-classdef.h:1231
octave_function * get_constructor_function(void)
Definition: ov-classdef.h:837
std::list< cdef_class > get_constructor_list(void) const
octave_idx_type numel(const octave_value_list &idx)
Definition: ov.h:411
static bool is_dummy_method(const octave_value &fcn)
Definition: ov-classdef.cc:403
static llvm::LLVMContext & context
Definition: jit-typeinfo.cc:76
std::string string_value(bool force=false) const
Definition: ov.h:908
octave_value_list subsref(const std::string &type, const std::list< octave_value_list > &idx, int nargout, size_t &skip, const cdef_class &context, bool auto_add)
void stash_function_name(const std::string &s)
Definition: ov-usr-fcn.h:294
static cdef_method make_method(const cdef_class &cls, const std::string &name, const octave_value &fcn, const std::string &m_access="public", bool is_static=false)
Definition: ov-classdef.cc:759
void error_with_id(const char *id, const char *fmt,...)
Definition: error.cc:615
tree_parameter_list * return_list(void)
Definition: ov-usr-fcn.h:379
nd deftypefn *octave_map m
Definition: ov-struct.cc:2058
void visit_prefix_expression(tree_prefix_expression &)
static void add(fptr f)
std::string name(void) const
Definition: pt-id.h:67
void mark_as_external(const std::string &dtype)
Definition: ov-classdef.h:1154
void put(const std::string &pname, const octave_value &val)
Definition: ov-classdef.h:248
static const cdef_class & meta_method(void)
Definition: ov-classdef.h:864
bool is_string(void) const
Definition: ov.h:578
bool check_access(void) const
octave_user_function * user_function_value(bool silent=false) const
Definition: ov.cc:1711
bool is_strict_superclass(const cdef_class &clsa, const cdef_class &clsb)
Definition: ov-classdef.cc:242
static cdef_class _meta_method
Definition: ov-classdef.h:893
static cdef_manager * instance
Definition: ov-classdef.h:1653
octave_value_list execute(const octave_value_list &args, int nargout, bool do_check_access=true, const std::string &who="")
Definition: ov-classdef.h:1125
static cdef_package lookup_package(const std::string &name)
void visit_no_op_command(tree_no_op_command &)
std::list< cdef_class > implicit_ctor_list
Definition: ov-classdef.h:740
void mark_as_class_method(void)
Definition: ov-usr-fcn.h:346
octave_value_list meta_subsref(const std::string &type, const std::list< octave_value_list > &idx, int nargout)
octave_value & assign(assign_op op, const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
Definition: ov.cc:1556
double tmp
Definition: data.cc:6300
is false
Definition: cellfun.cc:398
Cell get_packages(void) const
static octave_value_list package_get_classes(const octave_value_list &args, int)
octave_value retval
Definition: data.cc:6294
octave_value_list splice(octave_idx_type offset, octave_idx_type len, const octave_value_list &lst=octave_value_list()) const
Definition: ovl.cc:126
bool is_constant(void) const
Definition: ov-classdef.h:1012
static cdef_package _meta
Definition: ov-classdef.h:1391
#define panic_impossible()
Definition: error.h:40
static octave_value_list package_fromName(const octave_value_list &args, int)
static cdef_class _meta_class
Definition: ov-classdef.h:891
void visit_binary_expression(tree_binary_expression &)
octave_value find(const std::string &nm)
bool is_private_function(void) const
Definition: ov-fcn.h:116
std::list< tree_classdef_properties_block * > properties_list(void)
Definition: pt-classdef.h:548
void initialize_object(cdef_object &obj)
void visit_switch_case(tree_switch_case &)
octave_value get_value(bool do_check_access=true, const std::string &who="")
cdef_property make_attribute(const cdef_class &cls, const std::string &name)
Definition: ov-classdef.cc:753
static cdef_class _meta_package
Definition: ov-classdef.h:894
string_vector & sort(bool make_uniq=false)
Definition: str-vec.cc:74
static octave_value_list class_ge(const octave_value_list &args, int)
Definition: ov-classdef.cc:608
octave_value subsref(const std::string &type, const std::list< octave_value_list > &idx)
octave_value construct(const octave_value_list &args)
idx type
Definition: ov.cc:3129
tree_expression * expression(void)
Definition: pt-classdef.h:58
Definition: dMatrix.h:37
static cdef_class _meta_property
Definition: ov-classdef.h:892
cdef_class get_class(void) const
Definition: ov-classdef.h:1176
static octave_value_list class_eq(const octave_value_list &args, int)
Definition: ov-classdef.cc:609
void mark_as_meta_class(void)
Definition: ov-classdef.h:858
octave_value_list meta_subsref(const std::string &type, const std::list< octave_value_list > &idx, int nargout)
the sparsity preserving column transformation such that that defines the pivoting threshold can be given in which case it defines the c
Definition: lu.cc:138
octave_value get(const std::string &pname) const
Definition: ov-classdef.h:251
void install_package(const cdef_package &pack, const std::string &nm)
friend class cdef_object
Definition: ov-classdef.h:52
octave_value construct(const octave_value_list &args)
Definition: ov-classdef.h:840
cdef_package do_find_package(const std::string &name, bool error_if_not_found, bool load_if_not_found)
static bool is_superclass(const cdef_class &clsa, const cdef_class &clsb, bool allow_equal=true, int max_depth=-1)
Definition: ov-classdef.cc:218
cdef_property find_property(const std::string &nm)
Definition: ov-classdef.h:1235
virtual bool print_name_tag(std::ostream &os, const std::string &name) const
Definition: ov-base.cc:456
bool is_scalar(const dim_vector &dim)
Definition: Array-util.cc:115
void visit_octave_user_script(octave_user_script &)
static cdef_property make_property(const cdef_class &cls, const std::string &name, const octave_value &get_method=Matrix(), const std::string &get_access="public", const octave_value &set_method=Matrix(), const std::string &set_access="public")
Definition: ov-classdef.cc:716
cdef_object(void)
Definition: ov-classdef.h:189
octave_function * function_value(bool=false)
friend class octave_value
Definition: ov-base.h:211
octave_lvalue lvalue(void)
Definition: pt-decl.h:85
void setfield(const std::string &key, const Cell &val)
Definition: oct-map.cc:270
octave_classdef_superclass_ref(const octave_value_list &a)
static octave_idx_type find(octave_idx_type i, octave_idx_type *pp)
Definition: colamd.cc:112
octave_function * function_value(bool silent=false) const
Definition: ov.cc:1705
T & xelem(octave_idx_type n)
Definition: Array.h:455
octave_value_list do_multi_index_op(int nargout, const octave_value_list &idx)
void visit_if_command_list(tree_if_command_list &)
std::string class_name(void) const
Definition: ov-classdef.h:221
cdef_property find_property(const std::string &nm)
void warning(const char *fmt,...)
Definition: error.cc:788
virtual std::string name(void) const
Definition: pt-exp.h:103
std::map< std::string, cdef_property > get_property_map(int mode)
static int t_id
Definition: ov-classdef.h:1484
std::string type_name(void) const
Definition: ov.h:1232
void mark_as_classdef_constructor(void)
Definition: ov-usr-fcn.h:332
virtual octave_value rvalue1(int nargout=1)
Definition: pt-exp.cc:54
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:228
octave_value undef_subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
Definition: ov-classdef.cc:929
bool ok(void) const
Definition: ov-classdef.h:274
bool is_empty(void) const
Definition: ov.h:542
std::list< tree_statement * >::const_iterator const_iterator
Definition: base-list.h:41
static cdef_class make_meta_class(const std::string &name, const cdef_class &super)
Definition: ov-classdef.cc:705
octave_value make_idx_args(const std::string &type, const std::list< octave_value_list > &idx, const std::string &who)
Definition: ov-base.cc:1454
bool check_set_access(void) const
bool empty(void) const
Definition: ovl.h:98
Cell get_classes(void) const
Definition: ov-classdef.h:1368
void visit_function_def(tree_function_def &)
bool is_constructor(void) const
static octave_value_list class_fevalStatic(const octave_value_list &args, int nargout)
Definition: ov-classdef.cc:535
cdef_object to_cdef(const octave_value &val)
Definition: ov-classdef.h:1503
static OCTAVE_NORETURN void err_method_access(const std::string &from, const cdef_method &meth)
Definition: ov-classdef.cc:52
void mark_as_handle_class(void)
Definition: ov-classdef.h:852
static const std::string t_name
Definition: ov-classdef.h:1486
static octave_value_list package_get_functions(const octave_value_list &args, int)
void set_class(const cdef_class &cls)
Definition: ov-classdef.h:219
void run_constructor(cdef_object &obj, const octave_value_list &args)
Definition: ov-classdef.h:849
bool bool_value(bool warn=false) const
Definition: ov.h:819
=val(i)}if ode{val(i)}occurs in table i
Definition: lookup.cc:239
size_t size(void) const
Definition: base-list.h:49
cdef_object construct_object(const octave_value_list &args)
Definition: ov-classdef.h:843
void find_names(std::set< std::string > &names, bool all)
static int register_type(const std::string &, const std::string &, const octave_value &)
Definition: ov-typeinfo.cc:60
void visit_fcn_handle(tree_fcn_handle &)
std::map< std::string, cdef_property > get_property_map(int mode=property_normal)
Definition: ov-classdef.h:808
p
Definition: lu.cc:138
tree_expression * expression(void)
Definition: pt-stmt.h:86
bool is_meta_class(void) const
Definition: ov-classdef.h:860
static octave_value_list package_getAllPackages(const octave_value_list &, int)
void visit_anon_fcn_handle(tree_anon_fcn_handle &)
void visit_simple_assignment(tree_simple_assignment &t)
octave_map map(dims)
static void register_package(const cdef_package &pkg)
Definition: ov-classdef.h:1582
static octave_value make_fcn_handle(octave_builtin::fcn ff, const std::string &nm)
Definition: ov-classdef.cc:127
void mark_as_constructed(void)
Definition: ov-classdef.h:433
size_t length(void) const
Definition: base-list.h:50
octave_function * do_find_package_symbol(const std::string &pack_name)
void delete_object(cdef_object obj)
bool is_constructed_object(const std::string nm)
octave_value function(void) const
Definition: pt-funcall.h:78
defaults to zero A value of zero computes the digamma a value of
Definition: psi.cc:68
void stash_dispatch_class(const std::string &nm)
Definition: ov-fcn.h:101
cdef_class_rep * get_rep(void)
Definition: ov-classdef.h:880
bool is_partially_constructed_for(const cdef_class &cls) const
Definition: ov-classdef.h:284
elt_type & front(void)
Definition: base-list.h:97
std::string class_name(void) const
Definition: ov.h:1234
b
Definition: cellfun.cc:398
static octave_value_list class_get_superclasses(const octave_value_list &args, int)
Definition: ov-classdef.cc:484
bool print_name_tag(std::ostream &os, const std::string &name) const
Definition: ov-classdef.cc:981
octave_value subsref(const std::string &type, const std::list< octave_value_list > &idx)
virtual bool is_anonymous_function_of_class(const std::string &="") const
Definition: ov-fcn.h:122
tree_classdef_superclass_list * superclass_list(void)
Definition: pt-classdef.h:617
bool is_user_function(void) const
Definition: ov.h:717
Cell get_properties(int mode)
std::string get_name(void) const
Definition: ov-classdef.h:823
void resize(octave_idx_type n, const octave_value &rfv=octave_value())
Definition: ovl.h:100
void assign(const idx_vector &i, const Array< T > &rhs, const T &rfv)
Indexed assignment (always with resize & fill).
Definition: Array.cc:1133
std::map< std::string, cdef_method >::const_iterator method_const_iterator
Definition: ov-classdef.h:750
static std::string attribute_value_to_string(T *t, octave_value v)
cdef_object construct_object(const octave_value_list &args)
void delete_object(cdef_object obj)
Definition: ov-classdef.h:829
void visit_multi_assignment(tree_multi_assignment &t)
static const cdef_class & meta_class(void)
Definition: ov-classdef.h:862
octave_value_list subsref(const std::string &type, const std::list< octave_value_list > &idx, int nargout)
Definition: ov-classdef.cc:829
std::map< std::string, cdef_method >::iterator method_iterator
Definition: ov-classdef.h:749
Cell map2Cell(const std::map< T1, T2 > &m)
bool is_expression(void) const
Definition: pt-stmt.h:68
static OCTAVE_NORETURN void err_property_access(const std::string &from, const cdef_property &prop, bool is_set=false)
Definition: ov-classdef.cc:68
void visit_matrix(tree_matrix &)
void mark_as_constructed(void)
Definition: ov-classdef.h:287
static cdef_class lookup_class(const std::string &name, bool error_if_not_found=true, bool load_if_not_found=true)
Definition: ov-classdef.cc:158
static void unregister_class(const cdef_class &cls)
Definition: ov-classdef.h:1576
std::string class_name(void) const
Definition: ov-classdef.h:1172
cdef_method find_method(const std::string &nm, bool local=false)
void visit_complex_for_command(tree_complex_for_command &)
octave_value get_value(const cdef_object &obj, bool do_check_access=true, const std::string &who="")
Definition: ov-classdef.h:991
Cell get_methods(void)
Definition: ov-classdef.h:797
bool is_method_executing(const octave_value &ov, const cdef_object &obj)
Definition: ov-classdef.cc:424
void visit_try_catch_command(tree_try_catch_command &)
bool is_builtin(void) const
Definition: ov-classdef.h:826
void visit_switch_command(tree_switch_command &)
void visit_simple_for_command(tree_simple_for_command &)
std::string who
void visit_return_list(tree_return_list &)
void visit_while_command(tree_while_command &)
const std::string & package_name(void) const
Definition: pt-classdef.h:624
static octave_value_list package_get_packages(const octave_value_list &args, int)
std::list< cdef_class > ctor_list
tree_statement_list * body(void)
Definition: ov-usr-fcn.h:381
bool is_handle_class(void) const
Definition: ov-classdef.h:855
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:87
octave_function * do_find_method_symbol(const std::string &method_name, const std::string &class_name)
void install_property(const cdef_property &prop)
Definition: ov-classdef.h:801
void visit_colon_expression(tree_colon_expression &)
tree_expression * right_hand_side(void)
Definition: pt-assign.h:141
string_vector get_names(void)
Definition: ov-classdef.h:811
cdef_object copy(void) const
Definition: ov-classdef.h:235
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:854
void visit_do_until_command(tree_do_until_command &)
void visit_if_command(tree_if_command &)
virtual void accept(tree_walker &tw)=0
void visit_decl_init_list(tree_decl_init_list &)
tree_classdef_attribute_list * attribute_list(void)
Definition: pt-classdef.h:613
static cdef_class get_class_context(std::string &name, bool &in_constructor)
Definition: ov-classdef.cc:265
void print(std::ostream &os, bool pr_as_read_syntax=false)
Definition: ov-classdef.cc:946
virtual void print_with_name(std::ostream &output_buf, const std::string &name, bool print_padding=true)
Definition: ov-base.cc:479
static void create_instance(void)
void visit_if_clause(tree_if_clause &)
octave_value next_subsref(const std::string &type, const std::list< octave_value_list > &idx, size_t skip=1)
Definition: ov.cc:1462
octave_value_list & prepend(const octave_value &val)
Definition: ovl.cc:67
virtual bool is_identifier(void) const
Definition: pt-exp.h:61
static bool find_package(const std::string &package_name)
Definition: load-path.h:132
static std::list< std::string > get_all_package_names(bool only_top_level=true)
Definition: load-path.h:139
void visit_break_command(tree_break_command &)
Cell get_packages(void) const
Definition: ov-classdef.h:1374
bool is_constructed(void) const
Definition: ov-classdef.h:279
void visit_decl_elt(tree_decl_elt &)
bool is_instance_of(const std::string &cls_name) const
void mark_as_class_constructor(void)
Definition: ov-usr-fcn.h:330
Array< T > index(const idx_vector &i) const
Indexing without resizing.
Definition: Array.cc:718
octave_value subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs, int ignore_copies=0)
Definition: ov-classdef.h:261
iterator begin(void)
Definition: base-list.h:83
return octave_value(v1.char_array_value().concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string())? '\'': '"'))
void set_function(const octave_value &fcn)
Definition: ov-classdef.h:1143
octave_value subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
Definition: ov-classdef.cc:889
void visit_continue_command(tree_continue_command &)
static cdef_class find_class(const std::string &name, bool error_if_not_found=true, bool load_if_not_found=true)
Definition: ov-classdef.h:1531
bool is_abstract(void) const
Definition: ov-classdef.h:813
static void register_type(void)
Definition: ov-classdef.cc:821
bool is(const cdef_object &obj) const
Definition: ov-classdef.h:292
octave_value_list arguments(void) const
Definition: pt-funcall.h:80
static octave_value find(const std::string &name, const octave_value_list &args=octave_value_list(), bool skip_variables=false, bool local_funcs=true)
Definition: symtab.cc:1255
void stash_name_tags(const string_vector &nm)
Definition: ovl.h:144