ov-mex-fcn.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 1996-2012 John W. Eaton
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, see
00019 <http://www.gnu.org/licenses/>.
00020 
00021 */
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026 
00027 #include "oct-shlib.h"
00028 
00029 #include <defaults.h>
00030 #include "dynamic-ld.h"
00031 #include "error.h"
00032 #include "gripes.h"
00033 #include "oct-obj.h"
00034 #include "ov-mex-fcn.h"
00035 #include "ov.h"
00036 #include "profiler.h"
00037 #include "toplev.h"
00038 #include "unwind-prot.h"
00039 
00040 DEFINE_OCTAVE_ALLOCATOR (octave_mex_function);
00041 
00042 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_mex_function,
00043                                      "mex function", "mex function");
00044 
00045 octave_mex_function::octave_mex_function
00046   (void *fptr, bool fmex, const octave_shlib& shl,
00047    const std::string& nm)
00048   : octave_function (nm), mex_fcn_ptr (fptr), exit_fcn_ptr (0),
00049     have_fmex (fmex), sh_lib (shl)
00050 {
00051   mark_fcn_file_up_to_date (time_parsed ());
00052 
00053   std::string file_name = fcn_file_name ();
00054 
00055   system_fcn_file
00056     = (! file_name.empty ()
00057        && Voct_file_dir == file_name.substr (0, Voct_file_dir.length ()));
00058 }
00059 
00060 octave_mex_function::~octave_mex_function (void)
00061 {
00062   if (exit_fcn_ptr)
00063     (*exit_fcn_ptr) ();
00064 
00065   octave_dynamic_loader::remove_mex (my_name, sh_lib);
00066 }
00067 
00068 std::string
00069 octave_mex_function::fcn_file_name (void) const
00070 {
00071   return sh_lib.file_name ();
00072 }
00073 
00074 octave_time
00075 octave_mex_function::time_parsed (void) const
00076 {
00077   return sh_lib.time_loaded ();
00078 }
00079 
00080 octave_value_list
00081 octave_mex_function::subsref (const std::string& type,
00082                               const std::list<octave_value_list>& idx,
00083                               int nargout)
00084 {
00085   octave_value_list retval;
00086 
00087   switch (type[0])
00088     {
00089     case '(':
00090       {
00091         int tmp_nargout = (type.length () > 1 && nargout == 0) ? 1 : nargout;
00092 
00093         retval = do_multi_index_op (tmp_nargout, idx.front ());
00094       }
00095       break;
00096 
00097     case '{':
00098     case '.':
00099       {
00100         std::string nm = type_name ();
00101         error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
00102       }
00103       break;
00104 
00105     default:
00106       panic_impossible ();
00107     }
00108 
00109   // FIXME -- perhaps there should be an
00110   // octave_value_list::next_subsref member function?  See also
00111   // octave_user_function::subsref.
00112   //
00113   // FIXME -- Note that if a function call returns multiple
00114   // values, and there is further indexing to perform, then we are
00115   // ignoring all but the first value.  Is this really what we want to
00116   // do?  If it is not, then what should happen for stat("file").size,
00117   // for exmaple?
00118 
00119   if (idx.size () > 1)
00120     retval = retval(0).next_subsref (nargout, type, idx);
00121 
00122   return retval;
00123 }
00124 
00125 // FIXME -- shouldn't this declaration be a header file somewhere?
00126 extern octave_value_list
00127 call_mex (bool have_fmex, void *f, const octave_value_list& args,
00128           int nargout, octave_mex_function *curr_mex_fcn);
00129 
00130 octave_value_list
00131 octave_mex_function::do_multi_index_op (int nargout,
00132                                         const octave_value_list& args)
00133 {
00134   octave_value_list retval;
00135 
00136   if (error_state)
00137     return retval;
00138 
00139   if (args.has_magic_colon ())
00140     ::error ("invalid use of colon in function argument list");
00141   else
00142     {
00143       unwind_protect frame;
00144 
00145       octave_call_stack::push (this);
00146 
00147       frame.add_fcn (octave_call_stack::pop);
00148 
00149       try
00150         {
00151           BEGIN_PROFILER_BLOCK (profiler_name ())
00152           retval = call_mex (have_fmex, mex_fcn_ptr, args, nargout, this);
00153           END_PROFILER_BLOCK
00154         }
00155       catch (octave_execution_exception)
00156         {
00157           gripe_library_execution_error ();
00158         }
00159     }
00160 
00161   return retval;
00162 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines