view libinterp/octave-value/cdef-package.cc @ 27216:823b4bcf79fc

unless necessary for formatting or code, use ' instead of ` Files affected: doc/interpreter/TODO, etc/HACKING.md, examples/code/oregonator.cc, examples/code/oregonator.m, libgui/graphics/ObjectFactory.cc, libinterp/corefcn/defun-dld.h, libinterp/corefcn/defun.h, libinterp/corefcn/graphics.cc, libinterp/corefcn/ls-hdf5.cc, libinterp/corefcn/oct-stream.cc, libinterp/octave-value/cdef-class.cc, libinterp/octave-value/cdef-manager.cc, libinterp/octave-value/cdef-method.cc, libinterp/octave-value/cdef-object.cc, libinterp/octave-value/cdef-package.cc, libinterp/octave-value/cdef-property.cc, libinterp/octave-value/cdef-utils.cc, libinterp/octave-value/ov-classdef.cc, libinterp/octave-value/ov-java.cc, libinterp/octave-value/ov.h, libinterp/parse-tree/oct-parse.yy, liboctave/array/Array.h, liboctave/numeric/bsxfun.h, liboctave/util/oct-rl-hist.c, scripts/help/__unimplemented__.m, scripts/image/imformats.m, scripts/image/imwrite.m, scripts/image/private/__imread__.m, scripts/image/private/__imwrite__.m, scripts/java/org/octave/Matrix.java, scripts/linear-algebra/condeig.m, scripts/miscellaneous/inputParser.m, scripts/miscellaneous/publish.m, scripts/pkg/private/configure_make.m, scripts/special-matrix/gallery.m, scripts/web/weboptions.m, test/classdef/classdef.tst.
author John W. Eaton <jwe@octave.org>
date Wed, 26 Jun 2019 15:47:03 -0400
parents 711f23332204
children b442ec6dda5c
line wrap: on
line source

/*

Copyright (C) 2012-2019 Michael Goffioul

This file is part of Octave.

Octave is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Octave is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Octave; see the file COPYING.  If not, see
<https://www.gnu.org/licenses/>.

*/

#if defined (HAVE_CONFIG_H)
#  include "config.h"
#endif

#include <algorithm>
#include <iomanip>

#include "cdef-class.h"
#include "cdef-manager.h"
#include "cdef-utils.h"
#include "errwarn.h"
#include "interpreter-private.h"
#include "interpreter.h"
#include "load-path.h"
#include "ov-builtin.h"
#include "ov-classdef.h"
#include "ov-fcn-handle.h"
#include "ov-usr-fcn.h"
#include "parse.h"
#include "pt-assign.h"
#include "pt-classdef.h"
#include "pt-idx.h"
#include "pt-misc.h"
#include "pt-stmt.h"

// Define to 1 to enable debugging statements.
#define DEBUG_TRACE 0

namespace octave
{
  void
  cdef_package::cdef_package_rep::install_class (const cdef_class& cls,
                                                 const std::string& nm)
  {
    class_map[nm] = cls;

    member_count++;
  }

  void
  cdef_package::cdef_package_rep::install_function (const octave_value& fcn,
                                                    const std::string& nm)
  {
    function_map[nm] = fcn;
  }

  void
  cdef_package::cdef_package_rep::install_package (const cdef_package& pack,
                                                   const std::string& nm)
  {
    package_map[nm] = pack;

    member_count++;
  }

  template <typename T1, typename T2>
  Cell
  map2Cell (const std::map<T1, T2>& m)
  {
    Cell retval (1, m.size ());
    int i = 0;

    for (auto it = m.begin (); it != m.end (); ++it, ++i)
      retval(i) = to_ov (it->second);

    return retval;
  }

  Cell
  cdef_package::cdef_package_rep::get_classes (void) const
  {
    return map2Cell (class_map);
  }

  Cell
  cdef_package::cdef_package_rep::get_functions (void) const
  {
    return map2Cell (function_map);
  }

  Cell
  cdef_package::cdef_package_rep::get_packages (void) const
  {
    return map2Cell (package_map);
  }

  octave_value
  cdef_package::cdef_package_rep::find (const std::string& nm)
  {
    std::string symbol_name = get_name () + '.' + nm;

    interpreter& interp
      = __get_interpreter__ ("cdef_package::cdef_package_rep::find");

    return interp.find (symbol_name);
  }

  octave_value_list
  cdef_package::cdef_package_rep::meta_subsref
  (const std::string& type, const std::list<octave_value_list>& idx,
   int nargout)
  {
    octave_value_list retval;

    switch (type[0])
      {
      case '.':
        {
          if (idx.front ().length () != 1)
            error ("invalid meta.package indexing");

          std::string nm = idx.front ()(0).xstring_value ("invalid meta.package indexing, expected a symbol name");

#if DEBUG_TRACE
          std::cerr << "meta.package query: " << nm << std::endl;
#endif

          octave_value o = find (nm);

          if (! o.is_defined ())
            error ("member '%s' in package '%s' does not exist",
                   nm.c_str (), get_name ().c_str ());

          if (o.is_function ())
            {
              octave_function *fcn = o.function_value ();

              // NOTE: the case where the package query is the last
              // part of this subsref index is handled in the parse
              // tree, because there is some logic to handle magic
              // "end" that makes it impossible to execute the
              // function call at this stage.

              if (type.size () > 1
                  && ! fcn->accepts_postfix_index (type[1]))
                {
                  octave_value_list tmp_args;

                  retval = feval (o, tmp_args, nargout);
                }
              else
                retval(0) = o;

              if (type.size () > 1 && idx.size () > 1)
                retval = retval(0).next_subsref (nargout, type,
                                                 idx, 1);
            }
          else if (type.size () > 1 && idx.size () > 1)
            retval = o.next_subsref (nargout, type, idx, 1);
          else
            retval(0) = o;
        }
        break;

      default:
        error ("invalid meta.package indexing");
        break;
      }

    return retval;
  }

  void
  cdef_package::cdef_package_rep::meta_release (void)
  {
    // FIXME: Do we really want to unregister the package, as it
    //        could still be referenced by classes or sub-packages?
    //        If the package object is recreated later on, it won't
    //        match the one already referenced by those classes or
    //        sub-packages.

    cdef_manager& cdm
      = __get_cdef_manager__ ("cdef_package::cdef_package_rep::meta_release");

    // Don't delete the "meta" package.
    if (this != cdm.meta ().get_rep ())
      cdm.unregister_package (wrap ());
  }
}