Mercurial > octave
diff libinterp/octave-value/cdef-utils.cc @ 26772:d1419ac09564
split method, package, and property classes from cdef-class file
* cdef-method.cc, cdef-method.h, cdef-package.cc, cdef-package.h,
cdef-property.cc, cdef-property.h: New files.
* libinterp/octave-value/module.mk: Update.
* cdef-class.cc, cdef-class.h, cdef-manager.h, cdef-object.cc,
cdef-utils.cc, cdef-utils.h, ov-classdef.cc: Adapt as needed for new
file arrangement.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 22 Feb 2019 15:28:42 +0000 |
parents | 2f847e3e8d6b |
children | 568c2ab2782d |
line wrap: on
line diff
--- a/libinterp/octave-value/cdef-utils.cc Fri Feb 22 14:51:29 2019 +0000 +++ b/libinterp/octave-value/cdef-utils.cc Fri Feb 22 15:28:42 2019 +0000 @@ -25,7 +25,11 @@ #endif #include "call-stack.h" +#include "cdef-class.h" #include "cdef-manager.h" +#include "cdef-method.h" +#include "cdef-package.h" +#include "cdef-property.h" #include "cdef-utils.h" #include "interpreter-private.h" #include "ov-classdef.h" @@ -230,3 +234,115 @@ return get_class_context (dummy_string, dummy_bool); } + +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) +{ + if (acc.is_string ()) + { + std::string acc_s = acc.string_value (); + + if (acc_s == "public") + return true; + + cdef_class ctx = get_class_context (); + + // The access is private or protected, this requires a + // valid class context. + + if (ctx.ok ()) + { + if (acc_s == "private") + return (ctx == cls); + else if (acc_s == "protected") + { + if (is_superclass (cls, ctx)) + // Calling a protected method in a superclass. + return true; + else if (is_strict_superclass (ctx, cls)) + { + // Calling a protected method or property in a derived class. + // This is only allowed if the context class knows about it + // and has access to it. + + if (! meth_name.empty ()) + { + cdef_method m = ctx.find_method (meth_name); + + if (m.ok ()) + return check_access (ctx, m.get ("Access"), meth_name); + + return false; + } + else if (! prop_name.empty ()) + { + cdef_property p = ctx.find_property (prop_name); + + if (p.ok ()) + { + octave_value p_access = p.get (is_prop_set ? + "SetAccess" : + "GetAccess"); + + return check_access (ctx, p_access, meth_name, + prop_name, is_prop_set); + } + + return false; + } + else + panic_impossible (); + } + + return false; + } + else + panic_impossible (); + } + } + else if (acc.isobject ()) + { + cdef_class ctx = get_class_context (); + + // At this point, a class context is always required. + if (ctx.ok ()) + { + if (ctx == cls) + return true; + + cdef_class acc_cls (to_cdef (acc)); + + if (is_superclass (acc_cls, ctx)) + return true; + } + } + else if (acc.iscell ()) + { + Cell acc_c = acc.cell_value (); + + cdef_class ctx = get_class_context (); + + // At this point, a class context is always required. + + if (ctx.ok ()) + { + if (ctx == cls) + return true; + + for (int i = 0; i < acc.numel (); i++) + { + cdef_class acc_cls (to_cdef (acc_c(i))); + + if (is_superclass (acc_cls, ctx)) + return true; + } + } + } + else + error ("invalid property/method access in class `%s'", + cls.get_name ().c_str ()); + + return false; +}